anthropics / anthropics/claude-code
Windows: refresh-token rotation not persisted to .credentials.json; failed refresh blanks the store, locking out all fresh processes (2.1.220)
- Ngôn ngữ chính
- Python
- Star
- 145k
- Fork
- 23.1k
- Chỉ số merge pull request
- Chỉ số pull request đang chờ
Mô tả
## Summary
On Windows, long-running interactive sessions stayed healthy for 40+ hours while the on-disk `%USERPROFILE%\.claude\.credentials.json` was never updated with rotated tokens - its `refreshTokenExpiresAt` remained at (last login + ~24h). When a fresh headless process (`claude --print` from a scheduled task, same user) started after that horizon, it failed auth AND the CLI rewrote `.credentials.json` with empty `accessToken`/`refreshToken`, leaving every subsequent fresh process unable to authenticate until a manual `claude auth login`.
## Environment
- Claude Code 2.1.220 (native install, `%USERPROFILE%\.local\bin\claude.exe`), autoUpdates disabled
- Windows 11 Pro (always-on desktop, no sleep/wake involved)
- Claude Max (20x) subscription, OAuth login (no API key, no keychain/Credential Manager entries - file store only)
- 2-3 concurrent interactive sessions typically running, plus one nightly headless `claude --print` scheduled task under the same user account
## Timeline (all times local, measured from file metadata and task logs)
1. Aug 31 ~16:49 - last interactive `claude auth login` on the machine.
2. Sep 1 16:49 - `refreshTokenExpiresAt` in `.credentials.json` (login + ~24h). Between login and this point the file was never rewritten, while multiple long-running sessions continued working (presumably refreshing in memory).
3. Sep 2 00:05:04 - `.credentials.json` mtime updates: `accessToken` and `refreshToken` now empty strings (`expiresAt: 0`), other fields (scopes, subscriptionType, `refreshTokenExpiresAt` from step 2) retained.
4. Sep 2 00:05:10 - the scheduled headless `claude --print` logs 401 on every model attempted.
5. Long-running interactive sessions from before the horizon continued working throughout (one ran 40+ hours total on the Aug 31 login).
## Questions
1. Is refresh-token rotation supposed to persist back to `.credentials.json` on Windows? Here the on-disk refresh token appears to have remained the original from login (horizon login+24h) while live sessions kept working, so any fresh process inherits a stale/superseded token.
2. Is rewriting the store with empty tokens on a failed refresh intended (defensive clear) or a bug? It converts one failed refresh into "every future process is locked out" with no visible error until the next launch.
3. `troubleshoot-install.md` documents a pre-v2.1.211 double-refresh/revocation race ("Parallel sessions... coordinate its renewal so that only one process refreshes"). This machine is on 2.1.220 - is the coordination expected to cover a scheduled-task process starting fresh at a fixed time?
## Workaround in place
The scheduled task now authenticates via a `claude setup-token` one-year token injected as `CLAUDE_CODE_OAUTH_TOKEN` at runtime, which works well (and is a great facility) - filing this because the interactive-store behavior seems like it will bite anyone running scheduled headless work off a shared login.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Hướng nghiên cứu
Start by reproducing the Windows flow with concurrent interactive sessions and a scheduled `claude --print`, inspecting `%USERPROFILE%\.claude\.credentials.json` before and after token refresh and failed refresh. Compare the behavior with the coordination guidance in `troubleshoot-install.md`; done means rotated credentials persist safely and a failed refresh does not blank the shared store or leaves clear recovery behavior.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Lĩnh vực
- authentication, cli
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Sôi nổi
- Độ rõ ràng
- Cần làm rõ
- Mức phù hợp với người mới
- 35/100