fix(auth): clear active_provider when removing the active OAuth provider - #37648
Open
AhmetArif0 wants to merge 1 commit into
Open
fix(auth): clear active_provider when removing the active OAuth provider#37648AhmetArif0 wants to merge 1 commit into
AhmetArif0 wants to merge 1 commit into
Conversation
_clear_auth_store_provider() deleted providers[provider] from auth.json but left active_provider pointing to the removed provider. On the next launch get_active_provider() returned the stale name, credential-pool resolution found an empty pool, and raised "No inference provider configured" even when other providers were available. clear_provider_auth() (used by hermes logout) already clears active_provider at line 1412-1413. Apply the same guard in _clear_auth_store_provider() so every auth-remove path stays in sync.
teknium1
reviewed
Jul 13, 2026
teknium1
left a comment
Contributor
There was a problem hiding this comment.
Thanks for identifying the stale active_provider state. Current main still has the singleton-backed bug at agent/credential_sources.py:233-236, but the proposed condition needs one adjustment before it covers all active OAuth removals.
Problems
- The new guard remains inside the singleton-membership branch. Current Codex adds intentionally create pool-only
manual:device_codeentries (hermes_cli/auth_commands.py:316-324), while the removal registry routes that source to_remove_codex_device_code()(agent/credential_sources.py:415-417). With noproviders.openai-codexentry, the proposed guard never runs and leaves the active provider stale.
Suggested changes
- Clear and persist
active_providerwhenever it matches the requested provider, independently of whether a singleton was deleted; retain the helper's deletion-return semantics if needed for user-facing cleanup output. - Add an
auth_remove_command()regression for an active, pool-only Codexmanual:device_codeentry and assertactive_provideris cleared.
Automated hermes-sweeper review.
| providers_dict = auth_store.get("providers") | ||
| if isinstance(providers_dict, dict) and provider in providers_dict: | ||
| del providers_dict[provider] | ||
| if auth_store.get("active_provider") == provider: |
Contributor
There was a problem hiding this comment.
This guard only runs when providers[provider] still exists. Current hermes auth add openai-codex intentionally creates pool-only manual:device_code credentials (hermes_cli/auth_commands.py:316-324), and their removal is routed here via the Codex removal step. Clear and persist active_provider independently of singleton deletion so that active pool-only credentials do not leave stale provider state.
Open
19 tasks
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.
Problem
_clear_auth_store_provider()deletesproviders[provider]from auth.json but does notupdate
active_provider. After removal,get_active_provider()still returns the staleprovider name. On the next launch
is_provider_explicitly_configured()returnsTrueforit, credential-pool resolution finds an empty pool, and raises "No inference provider
configured" — even when other providers are still available.
Affected providers
All providers whose removal dispatches through
_clear_auth_store_provider:nous,openai-codex,xai-oauth,minimax-oauth(and any future provider that calls it).
Failure path
Fix
clear_provider_auth()(used byhermes logout) already nullsactive_providerwhen itmatches the removed provider (auth.py:1412-1413). Apply the same guard inside
_clear_auth_store_provider():Both changes happen inside the same
_auth_store_lock()context, so the write is atomic.Test plan
test_clear_auth_store_provider_clears_active_provider— removes the active provider, verifiesactive_providerisNonetest_clear_auth_store_provider_preserves_active_provider_for_other— removes a non-active provider, verifiesactive_provideris unchangedcredential_sourcestests pass