Skip to content

fix(cli): sync credential_pool on Codex re-auth - #33074

Closed
konsisumer wants to merge 1 commit into
NousResearch:mainfrom
konsisumer:fix/codex-reauth-sync-credential-pool
Closed

fix(cli): sync credential_pool on Codex re-auth#33074
konsisumer wants to merge 1 commit into
NousResearch:mainfrom
konsisumer:fix/codex-reauth-sync-credential-pool

Conversation

@konsisumer

Copy link
Copy Markdown
Contributor

What does this PR do?

Codex re-authentication via hermes setup / hermes model wrote the fresh OAuth pair to providers.openai-codex.tokens but never updated credential_pool.openai-codex. Because the runtime selects credentials from the pool (not from the provider singleton), the pool's device_code entry kept holding the now-consumed refresh token plus the stale last_error_* / last_status markers from the prior invalidation. The next request spent a dead token and got an immediate 401 token_invalidated from OpenAI.

This makes _save_codex_tokens update the singleton-seeded pool entries in lockstep with the provider tokens — within the same _auth_store_lock, so the write is atomic — and clears the entry's error state. Manual (manual:*) pool entries are independent credentials and are deliberately left untouched, matching the existing _sync_device_code_entry_to_auth_store convention.

Scope note: the linked issue also reports a secondary agent/codex_runtime.py bug (a null output field crashing parse_response). That is an unrelated change in a different module, so it is intentionally out of scope here and the issue is referenced with Refs rather than auto-closed.

Related Issue

Refs #33000

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • hermes_cli/auth.py: add _sync_codex_pool_entries() and call it from _save_codex_tokens() so re-auth updates the device_code credential_pool.openai-codex entries (access/refresh token, last_refresh) and clears last_status / last_error_* markers, atomically under _auth_store_lock.
  • tests/hermes_cli/test_auth_codex_provider.py: add test_save_codex_tokens_syncs_credential_pool covering the device_code entry sync, error-marker clearing, and that manual entries are left untouched.

How to Test

  1. Authenticate Hermes with the openai-codex provider, then re-auth via hermes setup / hermes model (e.g. after a token invalidation).
  2. Inspect ~/.hermes/auth.json: credential_pool.openai-codex[0] now carries the same access_token / refresh_token as providers.openai-codex.tokens, and its last_error_* / last_status fields are cleared.
  3. Restart the gateway and confirm API calls no longer fail with 401 token_invalidated.
  4. Automated: pytest tests/hermes_cli/test_auth_codex_provider.py -q (17 passing, including the new regression test).

Verified locally on macOS (darwin-arm64) with the repo venv; ruff check clean on the changed files and scripts/check-windows-footguns.py clean (the change is pure dict manipulation — no process, path, signal, or subprocess surface).

What platforms tested on

  • macOS on darwin-arm64 (local): pytest tests/hermes_cli/test_auth_codex_provider.py (17 passed), plus tests/agent/test_credential_pool.py and tests/hermes_cli/test_auth_commands.py (116 passed) with no regressions.
  • Linux / Windows / WSL2: not run locally; trusting CI. The change touches no platform-specific APIs.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run the relevant tests (pytest tests/hermes_cli/test_auth_codex_provider.py -q) and all pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS (darwin-arm64)

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

Codex re-auth via `hermes setup` / `hermes model` wrote fresh OAuth
tokens to providers.openai-codex.tokens but left the credential_pool
device_code entry holding the consumed refresh token and stale error
markers. Since the runtime selects from the pool, the next request
spent a dead token and got a 401 token_invalidated. Update the
singleton-seeded pool entries in lockstep and clear their error state.

Fixes NousResearch#33000
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/cli CLI entry point, hermes_cli/, setup wizard area/auth Authentication, OAuth, credential pools provider/copilot GitHub Copilot (ACP + Chat) labels May 27, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Salvaged onto current main via #33164 (merged as 2bbd534). Your authorship is preserved in git log on the fix commit. Thanks @konsisumer — clean diff, exactly the right scope (singleton pool entries in lockstep, manual entries deliberately untouched). Closes #33000.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have provider/copilot GitHub Copilot (ACP + Chat) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants