fix(anthropic): write scopes field to Claude Code credentials on token refresh#4118
Closed
ticketclosed-wontfix wants to merge 1 commit into
Closed
Conversation
…n refresh Claude Code >=2.1.81 checks for a 'scopes' array containing 'user:inference' in ~/.claude/.credentials.json before accepting stored OAuth tokens as valid. When Hermes refreshes the token, it writes only accessToken, refreshToken, and expiresAt — omitting the scopes field. This causes Claude Code to report 'loggedIn: false' and refuse to start, even though the token is valid. This commit: - Parses the 'scope' field from the OAuth refresh response - Passes it to _write_claude_code_credentials() as a keyword argument - Persists the scopes array in the claudeAiOauth credential store - Preserves existing scopes when the refresh response omits the field Tested against Claude Code v2.1.87 on Linux — auth status correctly reports loggedIn: true and claude --print works after this fix.
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.
What does this PR do?
Fixes a compatibility issue where Claude Code reports
loggedIn: falseand refuses to start when Hermes has refreshed the OAuth token.Root cause: Claude Code >=2.1.81 added a check that gates on a
scopesarray containing"user:inference"in~/.claude/.credentials.jsonbefore accepting stored OAuth tokens. When Hermes refreshes the token via_refresh_oauth_token(), it writes onlyaccessToken,refreshToken, andexpiresAt— omitting thescopesfield. Claude Code's internal auth validator (checkAndRefreshOAuthTokenIfNeeded) returnsfalseimmediately when scopes are missing, causing the CLI to report "Not logged in" even though the token is valid and works with the API.How I found it: Reverse-engineered the minified Claude Code v2.1.87 binary. The function
TS(H)checksH?.includes(oh)whereoh="user:inference". This is called frombW8(checkAndRefreshOAuthTokenIfNeeded) withK.scopesfrom the credential store. When scopes isundefined,TS()returnsfalseand the auth check bails.Related Issue
N/A (new discovery — no existing issue)
Type of Change
Changes Made
agent/anthropic_adapter.py: Parsescopefield from OAuth refresh response and pass to credential writeragent/anthropic_adapter.py: Addscopeskeyword argument to_write_claude_code_credentials()agent/anthropic_adapter.py: Persist scopes array inclaudeAiOauthcredential store; preserve existing scopes when refresh response omits the fieldHow to Test
claude auth status— should reportloggedIn: true(previously reportedfalse)echo "hello" | claude --print— should work (previously failed with "Not logged in")Checklist
Code
pytest tests/ -qand all tests pass (98 passed in test_anthropic_adapter.py, 2 passed in test_anthropic_oauth_flow.py)Documentation & Housekeeping
Screenshots / Logs
Before fix:
After fix (adding scopes to credentials file):