← Back to PRs

#2123: fix(auth): sync from Claude CLI keychain before OAuth refresh

by jorge123255 open 2026-01-26 07:44 View on GitHub →
agents
## Summary Fixes #2036 - OAuth token race condition with Claude Code CLI When both Claude Code CLI and Clawdbot share the same OAuth credentials, a race condition occurs: 1. Token expires at time H 2. Claude Code refreshes at H-5min → gets NEW tokens, writes to keychain 3. Clawdbot still has OLD tokens, tries to refresh → **fails** (old refresh token invalidated) ## Changes - Before attempting OAuth refresh for the `claude-cli` profile, check if the Claude Code CLI keychain has fresher valid tokens - If keychain has valid tokens, use those instead of attempting refresh - On refresh failure, retry reading from keychain as a fallback - Update the auth store with keychain credentials for future use ## Test plan - [x] Build passes (`npm run build`) - [x] Lint passes (`npm run lint`) - [x] Auth-profiles unit tests pass (44 tests) - [x] Manual end-to-end test with Telegram bot - confirmed working <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR mitigates an OAuth token refresh race for the `anthropic:claude-cli` profile when Claude Code CLI and another agent share credentials. It attempts to read fresher Claude CLI credentials (keychain/file via `readClaudeCliCredentials`) before performing an OAuth refresh, and also retries reading from the CLI credentials store after a refresh failure, updating the local auth profile store when it finds valid tokens. The changes live in `src/agents/auth-profiles/oauth.ts`, specifically around `refreshOAuthTokenWithLock` and the refresh error-handling path in `resolveApiKeyForProfile`, and are intended to keep the auth store in sync with the external CLI credential source to avoid invalid refresh token failures. <h3>Confidence Score: 3/5</h3> - Mostly safe to merge once a compile/lint-breaking import issue is fixed. - The functional change is scoped and follows existing auth-store patterns, but the current diff introduces a clear duplicate import that will fail TypeScript/lint, and the keychain sync paths should be re-verified after fixing that. - src/agents/auth-profiles/oauth.ts <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs