Skip to content

fix(agent): normalise last_status_at to float in PooledCredential.from_dict (#25516)#25531

Closed
Bartok9 wants to merge 1 commit into
NousResearch:mainfrom
Bartok9:fix/25516-pool-last-status-at-timestamp
Closed

fix(agent): normalise last_status_at to float in PooledCredential.from_dict (#25516)#25531
Bartok9 wants to merge 1 commit into
NousResearch:mainfrom
Bartok9:fix/25516-pool-last-status-at-timestamp

Conversation

@Bartok9

@Bartok9 Bartok9 commented May 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #25516 — GPT pool entries crash with TypeError on rehydration.

Root Cause

Pool state files serialise last_status_at as an ISO-8601 string (via to_dict() / JSON round-trip). When the entry is reloaded from disk and _exhausted_until() is called, it performs

return entry.last_status_at + _exhausted_ttl(entry.last_error_code)

which raises TypeError: can only concatenate str (not "int") to str — crashing every outbound request to a GPT-family provider until the pool state file is manually deleted.

Fix

Apply the existing _parse_absolute_timestamp() helper to the last_status_at field inside PooledCredential.from_dict(). This helper already handles ISO-8601 strings, epoch-millisecond integers, and float-epoch values and is used for all other timestamp fields in this module. Adding it here keeps last_status_at a float at all times, matching its declared type annotation and the expectations of _exhausted_until().

Changes

  • agent/credential_pool.py — 5-line guard in from_dict() after the dataclass is assembled; normalises last_status_at through _parse_absolute_timestamp() when the field is present and non-None.
  • tests/agent/test_credential_pool.py — two regression tests:
    • ISO-8601 string round-trip no longer raises TypeError; _exhausted_until() returns a float
    • epoch-millisecond integer is correctly divided to epoch-seconds

Before / After

# Before — rehydration from pool state file with ISO timestamp
entry.last_status_at  → "2026-05-11T08:23:20.891066+00:00"
_exhausted_until(entry) → TypeError: can only concatenate str (not "int") to str

# After
entry.last_status_at  → 1747050200.891066  (float)
_exhausted_until(entry) → 1747053800.891066  (float, valid future deadline)

Testing

python3 -m pytest tests/agent/test_credential_pool.py::test_from_dict_normalises_iso_last_status_at tests/agent/test_credential_pool.py::test_from_dict_normalises_epoch_ms_last_status_at -v
# 2 passed in 1.93s

…m_dict

Pool state files serialise last_status_at as an ISO-8601 string.
_exhausted_until() performs arithmetic directly on the field value
(entry.last_status_at + _exhausted_ttl(...)), which raises

    TypeError: can only concatenate str (not "int") to str

when the entry is rehydrated from disk — crashing every outbound
request to a GPT-family provider until the pool file is deleted.

Fix: apply _parse_absolute_timestamp() to the field in from_dict() so
it is always stored as a float epoch, matching its declared type
annotation and the expectations of _exhausted_until().  The same
helper already normalises ISO-8601 and epoch-millisecond values used
elsewhere in this module.

Add two regression tests:
- ISO-8601 string round-trip no longer raises TypeError
- epoch-millisecond integer is divided correctly to epoch-seconds

Fixes NousResearch#25516
@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround comp/agent Core agent loop, run_agent.py, prompt builder labels May 14, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #25528 — both fix #25516 (ISO-8601 last_status_at not parsed on rehydration, crashing _exhausted_until()).

@Bartok9

Bartok9 commented May 14, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #25528 which has a more comprehensive fix (from_dict normalisation + defence-in-depth _exhausted_until guard). Closing in favour of @kagura-agent's PR.

@Bartok9 Bartok9 closed this May 14, 2026
@konsisumer konsisumer mentioned this pull request May 31, 2026
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent loop, run_agent.py, prompt builder P1 High — major feature broken, no workaround type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Type issue in GPT pools

2 participants