Nothing open on GitHub. Fix merged in #21264 on 7 May 2026. Check it covers your case.
The short answer
0open issues
0open PRs
3items grouped
- Known?
- Yes. 3 related items grouped here, 1 issue already closed.
- Fix event
- A fix was merged to main in PR #21264. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
resolved, deciding PR #21264. That is separate from the fix event. - Still open
- Nothing open on GitHub.
These items address a problem where a transient 401 error causes a credential to be blacklisted for 24 hours, with proposed fixes to shorten that cooldown period. The concern is especially acute for single-key setups where one bad response locks out the only available credential.
Open issues0
Open PRs0
Fixes on record
-
#21264 fix(auth): shorten credential 401 cooldown to 5 minutes (salvage #19267)
files:
agent/credential_pool.py,tests/agent/test_credential_pool.pyShow the diff
-
agent/credential_pool.py@@ -68,8 +68,10 @@ def _load_config_safe() -> Optional[dict]: } # Cooldown before retrying an exhausted credential. -# 429 (rate-limited) and 402 (billing/quota) both cool down after 1 hour. +# Transient 401 auth failures cool down briefly so single-key setups can recover. +# 429 (rate-limited), 402 (billing/quota), and other failures cool down after 1 hour. # Provider-supplied reset_at timestamps override these defaults. +EXHAUSTED_TTL_401_SECONDS = 5 * 60 # 5 minutes EXHAUSTED_TTL_429_SECONDS = 60 * 60 # 1 hour EXHAUSTED_TTL_DEFAULT_SECONDS = 60 * 60 # 1 hour @@ -190,6 +192,8 @@ def _is_manual_source(source: str) -> bool: def _exhausted_ttl(error_code: Optional[int]) -> int: """Return cooldown seconds based on the HTTP status that caused exhaustion.""" + if error_code == 401: + return EXHAUSTED_TTL_401_SECONDS if error_code == 429: return EXHAUSTED_TTL_429_SECONDS return EXHAUSTED_TTL_DEFAULT_SECONDS -
tests/agent/test_credential_pool.py@@ -250,6 +250,42 @@ def test_exhausted_402_entry_resets_after_one_hour(tmp_path, monkeypatch): assert entry.last_status == "ok" +def test_exhausted_401_entry_resets_after_five_minutes(tmp_path, monkeypatch): + """Transient auth failures should not strand single-key setups for an hour.""" + monkeypatch.setenv("HERMES_HOME", str(tmp_path / "hermes")) + _write_auth_store( + tmp_path, + { + "version": 1, + "credential_pool": { + "openrouter": [ + { + "id": "cred-1", + "label": "primary", + "auth_type": "api_key", + "priority": 0, + "source": "manual", + "access_token": "***", + "base_url": "https://openrouter.ai/api/v1", + "last_status": "exhausted", + "last_status_at": time.time() - 310, + "last_error_code": 401, + } + ] + }, + }, + ) + + from agent.credential_pool import load_pool + + pool = load_pool("openrouter") + entry = pool.select() + + assert entry is not None + assert entry.id == "cred-1" + assert entry.last_status == "ok" + + def test_explicit_reset_timestamp_overrides_default_429_ttl(tmp_path, monkeypatch): monkeypatch.setenv("HERMES_HOME", str(tmp_path / "hermes")) # Prevent auto-seeding from Codex CLI tokens on the host
-
1 PR closed without merging
From the close comments: closed without comment 1
- #19267 fix(auth): shorten credential 401 cooldown · closed without comment
Closed issues · 1
- Closed#5668Transient 401 blacklists credential for 24 hours — breaks single-key setups
How this cluster was grouped
-
Link evidence (
structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference. -
Pairwise link density
0.67: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the LabAt a glance
- Subsystem
- agent
- Merged PRs
- #21264
- Closed issues
- 1
- Attempts
- 1 PR closed without merging
- Fix link checked
- 7 May 2026