anthropics / anthropics/claude-code

Windows: VS Code panel shows 'OAuth session expired and could not be refreshed' although re-login succeeds (stale-process refresh race + resumed session re-renders old auth error)

Đang mở
#92,630 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
area:auth bug has repro platform:vscode platform:windows
Ngôn ngữ chính
Python
Star
145k
Fork
23.1k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

# Bug: VS Code extension appears stuck in "Failed to authenticate: OAuth session expired and could not be refreshed" even after successful re-login

## Environment

- Windows 11 Pro (10.0.26200)
- VS Code extension `anthropic.claude-code` **2.1.263** (bundled native binary 2.1.263)
- CLI `claude` 2.1.263 (native install, `~\.local\bin\claude.exe`)
- Auth: claude.ai OAuth (Team plan), credentials in `%USERPROFILE%\.claude\.credentials.json` (plaintext file store; `tengu_windows_credman` flag is off, no Credential Manager entries)
- Other Claude surfaces running on the same machine: CLI sessions in terminals, Claude Desktop app

## Symptom

The VS Code side panel showed **"Failed to authenticate: OAuth session expired and could not be refreshed"** while a concurrently running CLI session in a plain PowerShell terminal worked fine with the same `.credentials.json`. Repeated sign-outs and browser sign-ins from the panel appeared to change nothing — the panel showed the same error immediately after completing each browser OAuth flow, for over an hour.

## What log forensics showed

Digging through the exthost logs (`Claude VSCode.log`) and correlating with `.credentials.json` mtimes revealed the sign-ins were **actually succeeding** the whole time:

1. Panel login (`{"type":"login","method":"claudeai"}`) delegates to a spawned SDK `claude.exe` session (`loginViaQuery` → `claudeAuthenticate` → `claudeOAuthWaitForCompletion`).
2. After completing the browser flow, a fresh valid token was written to `.credentials.json` (verified: mtime updated seconds after the browser redirect, new `expiresAt` ~8h out, and the *extension's own bundled* `native-binary\claude.exe` run headless from a terminal with that file authenticated fine and answered a `-p` prompt).
3. Yet the panel surfaced the "OAuth session expired and could not be refreshed" error (which is generated inside the CLI binary — the `authentication_failed` / `sY` error path) right as/after login completed.

Contributing factors observed:

- **Multiple concurrent `claude.exe` processes** are spawned by the extension (config-cache loader + chat session + login helper), plus independent CLI terminal sessions and the Desktop app. With refresh-token rotation, a stale process holding a rotated-away refresh token keeps failing and its error surfaces in the panel — the binary even ships a sibling message for this ("Failed to refresh OAuth token: another Claude Code process is refreshing it or exited mid-refresh"), but what the user is shown is the misleading "session expired" variant. This looks like the Windows-file-store analog of #79685 / #72017.
- **`/logout` in the panel vs the `Claude Code: Logout` command clear different state.** The panel `/logout` + re-login path never cleared the extension-side auth state, so the extension kept reporting the stale copy ("OAuth tokens found in secure storage") while fresh logins landed in the file. Only the Command Palette `Claude Code: Logout` produced "No authentication found".
- **The final UX trap:** after everything was actually fixed (valid token on disk, extension reading it, `fetchUtilization: 200`, bootstrap ok, session hooks running), reopening VS Code **resumed the previous conversation, which re-renders the historical auth-error bubble as the newest content in the panel**. This is indistinguishable from a live auth failure and makes the user believe re-login failed again — sending any new message works fine. This alone probably explains many "re-login doesn't help" reports.

## Suggested fixes

1. Render historical/transcript error bubbles from resumed sessions visually distinct from live errors (or timestamp them), so a restored conversation can't impersonate a current auth failure.
2. In the login completion path, don't surface a refresh failure from a *different/stale* process while `claudeOAuthWaitForCompletion` has actually succeeded; re-check the credential store after the exchange before reporting failure.
3. Serialize token refresh across processes on Windows (lockfile around `.credentials.json` refresh) to avoid rotation races between the extension's spawned processes, terminal CLI sessions, and the Desktop app.
4. Make panel `/logout` and `Claude Code: Logout` clear the same state, or remove one.

## Workaround that ended the loop

1. Command Palette → `Claude Code: Logout` (not `/logout` in the panel) — this actually cleared auth state ("No authentication found").
2. Sign in once from the panel (browser flow) — writes a fresh token family to `.credentials.json`.
3. Fully close VS Code so no stale `claude.exe` helpers survive, reopen — panel is authenticated; ignore the stale error bubble at the end of the resumed conversation.

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 with the `Claude VSCode.log` evidence and the `loginViaQuery` → `claudeAuthenticate` → `claudeOAuthWaitForCompletion` login path, comparing it with the `.credentials.json` state and resumed-panel behavior. The issue proposes four possible fixes rather than naming a single entry point or test; done would require selecting and validating one scoped fix for stale refresh errors, logout state, or historical auth-error rendering.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
python, vscode
Lĩnh vực
authentication, desktop
Loại issue
Lỗi
Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
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

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.