fix(gateway): classify Codex 429 quota as rate-limit, not missing credentials - #33168
Merged
Conversation
…dentials When the Codex OAuth token endpoint returns 429 (usage-limit / quota exhaustion), refresh_codex_oauth_pure raised a generic auth error that the gateway surfaced as 'Primary provider auth failed: No Codex credentials stored. Run hermes auth', prompting re-auth that cannot lift a quota cap. Classify 429 distinctly (codex_rate_limited, relogin_required=False) with a non-alarming quota message that honors Retry-After, log it as 'Primary provider rate-limited (429)', and stop format_auth_error from appending the re-authenticate remediation. Also log the fallback provider's literal config key instead of the resolved runtime category. Refs #32790
Contributor
🔎 Lint report:
|
Two tests in test_verbose_command.py asserted Telegram's tool_progress default was "new" and expected /verbose to cycle that to "all". The default has since been overridden to "off" in gateway/display_config.py (_PLATFORM_DEFAULTS for telegram — tier-1 inbox preset that keeps mobile chats final-answer-first), making the first /verbose invocation cycle off → new, not all → verbose. The behavioral change was intentional; the tests were stale and missing from the same commit. Surfaced as a pre-existing failure on origin/main during CI for the unrelated #33164 / #33168 Codex auth salvages.
19 tasks
This was referenced May 28, 2026
1 task
mathias3
pushed a commit
to mathias3/hermes-agent
that referenced
this pull request
May 28, 2026
Two tests in test_verbose_command.py asserted Telegram's tool_progress default was "new" and expected /verbose to cycle that to "all". The default has since been overridden to "off" in gateway/display_config.py (_PLATFORM_DEFAULTS for telegram — tier-1 inbox preset that keeps mobile chats final-answer-first), making the first /verbose invocation cycle off → new, not all → verbose. The behavioral change was intentional; the tests were stale and missing from the same commit. Surfaced as a pre-existing failure on origin/main during CI for the unrelated NousResearch#33164 / NousResearch#33168 Codex auth salvages.
Bryce-huang
pushed a commit
to wbkunlun/hermes-agent
that referenced
this pull request
May 29, 2026
Two tests in test_verbose_command.py asserted Telegram's tool_progress default was "new" and expected /verbose to cycle that to "all". The default has since been overridden to "off" in gateway/display_config.py (_PLATFORM_DEFAULTS for telegram — tier-1 inbox preset that keeps mobile chats final-answer-first), making the first /verbose invocation cycle off → new, not all → verbose. The behavioral change was intentional; the tests were stale and missing from the same commit. Surfaced as a pre-existing failure on origin/main during CI for the unrelated NousResearch#33164 / NousResearch#33168 Codex auth salvages. #AI commit#
gweeteve
pushed a commit
to gweeteve/hermes-agent
that referenced
this pull request
Jun 2, 2026
Two tests in test_verbose_command.py asserted Telegram's tool_progress default was "new" and expected /verbose to cycle that to "all". The default has since been overridden to "off" in gateway/display_config.py (_PLATFORM_DEFAULTS for telegram — tier-1 inbox preset that keeps mobile chats final-answer-first), making the first /verbose invocation cycle off → new, not all → verbose. The behavioral change was intentional; the tests were stale and missing from the same commit. Surfaced as a pre-existing failure on origin/main during CI for the unrelated NousResearch#33164 / NousResearch#33168 Codex auth salvages.
alt-glitch
pushed a commit
that referenced
this pull request
Jun 14, 2026
Two tests in test_verbose_command.py asserted Telegram's tool_progress default was "new" and expected /verbose to cycle that to "all". The default has since been overridden to "off" in gateway/display_config.py (_PLATFORM_DEFAULTS for telegram — tier-1 inbox preset that keeps mobile chats final-answer-first), making the first /verbose invocation cycle off → new, not all → verbose. The behavioral change was intentional; the tests were stale and missing from the same commit. Surfaced as a pre-existing failure on origin/main during CI for the unrelated #33164 / #33168 Codex auth salvages.
T02200059
pushed a commit
to T02200059/hermes-agent
that referenced
this pull request
Jun 18, 2026
Two tests in test_verbose_command.py asserted Telegram's tool_progress default was "new" and expected /verbose to cycle that to "all". The default has since been overridden to "off" in gateway/display_config.py (_PLATFORM_DEFAULTS for telegram — tier-1 inbox preset that keeps mobile chats final-answer-first), making the first /verbose invocation cycle off → new, not all → verbose. The behavioral change was intentional; the tests were stale and missing from the same commit. Surfaced as a pre-existing failure on origin/main during CI for the unrelated NousResearch#33164 / NousResearch#33168 Codex auth salvages.
xyshanren
pushed a commit
to xyshanren/hermes-agent-cn
that referenced
this pull request
Jun 25, 2026
Two tests in test_verbose_command.py asserted Telegram's tool_progress default was "new" and expected /verbose to cycle that to "all". The default has since been overridden to "off" in gateway/display_config.py (_PLATFORM_DEFAULTS for telegram — tier-1 inbox preset that keeps mobile chats final-answer-first), making the first /verbose invocation cycle off → new, not all → verbose. The behavioral change was intentional; the tests were stale and missing from the same commit. Surfaced as a pre-existing failure on origin/main during CI for the unrelated NousResearch#33164 / NousResearch#33168 Codex auth salvages.
waefrebeorn
pushed a commit
to waefrebeorn/slermes
that referenced
this pull request
Jul 2, 2026
Two tests in test_verbose_command.py asserted Telegram's tool_progress default was "new" and expected /verbose to cycle that to "all". The default has since been overridden to "off" in gateway/display_config.py (_PLATFORM_DEFAULTS for telegram — tier-1 inbox preset that keeps mobile chats final-answer-first), making the first /verbose invocation cycle off → new, not all → verbose. The behavioral change was intentional; the tests were stale and missing from the same commit. Surfaced as a pre-existing failure on origin/main during CI for the unrelated NousResearch#33164 / NousResearch#33168 Codex auth salvages.
santhreal
pushed a commit
to santhreal/hermes-agent
that referenced
this pull request
Jul 13, 2026
Two tests in test_verbose_command.py asserted Telegram's tool_progress default was "new" and expected /verbose to cycle that to "all". The default has since been overridden to "off" in gateway/display_config.py (_PLATFORM_DEFAULTS for telegram — tier-1 inbox preset that keeps mobile chats final-answer-first), making the first /verbose invocation cycle off → new, not all → verbose. The behavioral change was intentional; the tests were stale and missing from the same commit. Surfaced as a pre-existing failure on origin/main during CI for the unrelated NousResearch#33164 / NousResearch#33168 Codex auth salvages.
donbowman
pushed a commit
to donbowman/hermes-agent
that referenced
this pull request
Jul 13, 2026
Two tests in test_verbose_command.py asserted Telegram's tool_progress default was "new" and expected /verbose to cycle that to "all". The default has since been overridden to "off" in gateway/display_config.py (_PLATFORM_DEFAULTS for telegram — tier-1 inbox preset that keeps mobile chats final-answer-first), making the first /verbose invocation cycle off → new, not all → verbose. The behavioral change was intentional; the tests were stale and missing from the same commit. Surfaced as a pre-existing failure on origin/main during CI for the unrelated NousResearch#33164 / NousResearch#33168 Codex auth salvages.
Gravezzz
pushed a commit
to Gravezzz/hermes-agent
that referenced
this pull request
Jul 21, 2026
Two tests in test_verbose_command.py asserted Telegram's tool_progress default was "new" and expected /verbose to cycle that to "all". The default has since been overridden to "off" in gateway/display_config.py (_PLATFORM_DEFAULTS for telegram — tier-1 inbox preset that keeps mobile chats final-answer-first), making the first /verbose invocation cycle off → new, not all → verbose. The behavioral change was intentional; the tests were stale and missing from the same commit. Surfaced as a pre-existing failure on origin/main during CI for the unrelated NousResearch#33164 / NousResearch#33168 Codex auth salvages.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Salvage of #33080 (@konsisumer) onto current main.
Summary
When the Codex OAuth token endpoint returns 429 (usage-limit / quota exhaustion),
refresh_codex_oauth_pureraised a generic auth error. The gateway caught it as anAuthErrorand surfacedPrimary provider auth failed: No Codex credentials stored. Run \hermes auth`` to the operator and to the chat reply — misleading, because the stored credentials are valid and re-authenticating cannot lift a usage cap.This PR separates error classification (a 429 is a transient rate-limit/quota cap) from remediation copy ("re-authenticate"):
code=codex_rate_limited,relogin_required=False) with a non-alarming message that honorsRetry-AfterPrimary provider rate-limited (429)instead of "auth failed"providerkey from config (e.g.ollama) instead of swallowing itChanges
gateway/run.py: classify 429 as rate-limit at the gateway error-formatting layerhermes_cli/auth.py: newcodex_rate_limitederror code;refresh_codex_oauth_pureraises with explicit classificationtests/hermes_cli/test_auth_codex_provider.py: regression coverage for the 429-vs-401 distinctionValidation
tests/hermes_cli/test_auth_codex_provider.pyAttribution
Cherry-picked from @konsisumer's #33080 (clean cherry-pick, no conflicts against current main after #33164 also landed).
Follow-on: also fix pre-existing test_verbose_command failures
Surfaced during CI on #33164 — two tests in
tests/gateway/test_verbose_command.pyhad stale assertions about Telegram'stool_progressdefault. The default was changed from"new"to"off"(tier-1 inbox preset ingateway/display_config.pykeeping mobile chats final-answer-first), but the tests still expected the old cycle behavior (new → all). Updated to match current behavior (off → new).This is a zero-risk test-only fix unrelated to the Codex 429 classification — surfacing it here so the PR's CI goes green rather than carrying the pre-existing failure as a known-bad signal.
Infographic