[BUG] Logging in via VS Code extension does not set `hasCompletedOnboarding`, so the CLI TUI forces the full onboarding/login flow in a fresh `CLAUDE_CONFIG_DIR`
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When the first login for a config directory is performed through the VS Code extension, the extension writes valid credentials (.credentials.json) and account info (oauthAccount in .claude.json), but never sets hasCompletedOnboarding / lastOnboardingVersion. As a result, launching the interactive CLI (claude) against the same config directory starts the full first-run onboarding flow including the login screen, even though the stored OAuth token is valid — claude -p "hello" works fine with the same config dir.
This is easy to hit with a multi-account setup using CLAUDE_CONFIG_DIR (e.g. personal account in the default ~/.claude, work Claude Enterprise account in ~/.claude-work switched via direnv + the extension's claudeCode.claudeProcessWrapper): if the work account's first login happens in the extension, the CLI then appears to be logged out for that account.
Analysis:
- The installed extension bundle (
extension.js, v2.1.170) contains zero references tohasCompletedOnboarding— the extension performs auth/onboarding entirely in its own webview UI and never records the CLI's onboarding completion state. - The interactive TUI gates on the onboarding state rather than on credential validity, so it replays onboarding even though authentication would succeed.
- Manually adding
"hasCompletedOnboarding": true(andlastOnboardingVersion) to the affected.claude.jsonfixes it: the TUI then starts normally, already authenticated.
Related earlier reports (same family, different triggers):
- #29029 — extension rewrote
~/.claude.jsonand strippedhasCompletedOnboarding(closed as stale, not fixed) - #65725 —
claude auth loginalso "does not create enough configuration state", TUI re-runs the auth flow
What Should Happen?
Login state should be sufficient for the TUI: if valid credentials exist for the config dir (regardless of whether they were created by the CLI, the VS Code extension, or claude auth login), the interactive CLI should not force the login/onboarding flow — or the extension should write the same onboarding-completion state the CLI does.
Error Messages/Logs
# Same config dir, same moment:
$ CLAUDE_CONFIG_DIR=~/.claude-work claude -p "hello" # works, returns a response
$ CLAUDE_CONFIG_DIR=~/.claude-work claude # starts onboarding + login screen
Steps to Reproduce
- Pick a fresh config dir:
export CLAUDE_CONFIG_DIR=~/claude-test(no prior CLI usage) - In VS Code (extension
anthropic.claude-codev2.1.170), make the extension use that config dir (e.g. viaclaudeCode.environmentVariablesor aclaudeCode.claudeProcessWrapperscript), open the Claude panel and complete sign-in - Observe
$CLAUDE_CONFIG_DIR/.credentials.jsonexists andclaude -p "hello"succeeds - Run interactive
claudein a terminal with the sameCLAUDE_CONFIG_DIR→ full onboarding + login flow starts - Add
"hasCompletedOnboarding": trueto$CLAUDE_CONFIG_DIR/.claude.json→ interactiveclaudenow starts normally, authenticated
Claude Model
Not sure / Multiple models
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.170 (Claude Code)
Platform
Anthropic API
Operating System
Other Linux
Terminal/Shell
VS Code integrated terminal
Additional Information
- Auth detail: Claude.ai subscription accounts (one personal, one Enterprise) via OAuth — not API key auth
- OS: Arch Linux; shell: fish. The VS Code extension runs on this machine via Remote SSH (extension host on the Linux side)
- The CLI-side behavior is terminal-independent: reproduces both in the VS Code integrated terminal and in a plain SSH session (wezterm + fish)
- VS Code extension version: 2.1.170 (
anthropic.claude-code, linux-x64; bundled native binary is also 2.1.170) - Not a regression (verified): I checked
extension.jsacross marketplace versions 1.0.31, 1.0.109, 2.0.10, 2.1.0, and 2.1.170 — none of them referencehasCompletedOnboarding, so the extension's GUI sign-in has never recorded onboarding state since the webview UI was introduced. (In the pre-webview 1.0.x era the extension ran the CLI TUI directly, so login went through the TUI's own onboarding and the mismatch could not occur.) - Workaround for anyone hitting this: copy
hasCompletedOnboarding/lastOnboardingVersionfrom a working.claude.jsoninto the affected config dir's.claude.json.