Skip to content

fix(poller): fall back to the desktop token when the CLI token is expired - #194

Open
wuhaotian2026-svg wants to merge 1 commit into
CodeZeno:mainfrom
wuhaotian2026-svg:fix/desktop-token-fallback-when-cli-expired
Open

wuhaotian2026-svg wants to merge 1 commit into
CodeZeno:mainfrom
wuhaotian2026-svg:fix/desktop-token-fallback-when-cli-expired

Conversation

@wuhaotian2026-svg

Copy link
Copy Markdown

Summary

  • When ~/.claude/.credentials.json exists but holds an expired access token and the CLI refresh cannot run, the default Claude profile currently ends in TokenExpired, even though the Claude desktop app is signed in and keeps its own token cache fresh.
  • The existing desktop fallback only runs when the credentials file has no usable token at all (read_credentials_from_source returns None). A stale but present token never reaches it.
  • This change makes poll_account try the desktop token cache after a failed refresh. A refresh that succeeds is still used first.
  • The fallback keeps the existing restrictions: it applies only to the default CLI credentials path (desktop_credentials_for_default_path), is skipped when CLAUDE_CONFIG_DIR is set, never replaces a desktop source with itself, and only accepts a desktop token that is not expired. Custom or multi-account profiles stay pinned to their own source.

How I hit it: Windows 11, Microsoft Store build of the Claude desktop app (data under %LOCALAPPDATA%\Claude-Data\claude_*), Claude CLI installed via WinGet. The CLI had been signed in once, so .credentials.json held a token that later expired. The log showed "Skipping Claude token refresh: unable to determine the CLI version", and the widget showed the red ! until I signed in to the CLI again, which only lasted until that token expired.

Related: #183 (desktop credentials not found in the migrated data folder). That path discovery is already handled on main; this PR covers the separate case where a stale CLI token hides a working desktop token.

Testing

  • cargo fmt --all -- --check: clean.

  • cargo test --locked --release: 602 passed, 0 failed, 6 ignored.

  • cargo build --locked --release: succeeded.

  • Manual, on the setup described above, with --diagnose (log lines redacted):

    Skipping Claude token refresh: unable to determine the CLI version. ...
    using the Claude desktop app token cache
    default profile fell back to the Claude desktop app token cache
    stale CLI token replaced by the Claude desktop app token cache
    http GET api.anthropic.com/api/oauth/usage -> 200
    Claude Code account Default usage received: session=<n> weekly=<n> stale=false
    

    Before the change, the same setup logged usage poll failed: TokenExpired.

  • Not covered: no new unit test for the new branch. It needs a decryptable desktop token cache (DPAPI + AES-GCM), which I did not want to fake with fixtures. Happy to add a test if you can suggest a seam for it.

Checklist

  • I have read CONTRIBUTING.md and CODE_OF_CONDUCT.md.
  • The change is focused and contains no credentials or sensitive data.
  • I have added or updated relevant documentation and tests, where applicable. (no test, see above)
  • I have left changelog and version changes to maintainers unless requested.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant