[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`

Open 💬 0 comments Opened Jun 10, 2026 by sksat

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 to hasCompletedOnboarding — 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 (and lastOnboardingVersion) to the affected .claude.json fixes it: the TUI then starts normally, already authenticated.

Related earlier reports (same family, different triggers):

  • #29029 — extension rewrote ~/.claude.json and stripped hasCompletedOnboarding (closed as stale, not fixed)
  • #65725 — claude auth login also "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

  1. Pick a fresh config dir: export CLAUDE_CONFIG_DIR=~/claude-test (no prior CLI usage)
  2. In VS Code (extension anthropic.claude-code v2.1.170), make the extension use that config dir (e.g. via claudeCode.environmentVariables or a claudeCode.claudeProcessWrapper script), open the Claude panel and complete sign-in
  3. Observe $CLAUDE_CONFIG_DIR/.credentials.json exists and claude -p "hello" succeeds
  4. Run interactive claude in a terminal with the same CLAUDE_CONFIG_DIR → full onboarding + login flow starts
  5. Add "hasCompletedOnboarding": true to $CLAUDE_CONFIG_DIR/.claude.json → interactive claude now 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.js across marketplace versions 1.0.31, 1.0.109, 2.0.10, 2.1.0, and 2.1.170 — none of them reference hasCompletedOnboarding, 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 / lastOnboardingVersion from a working .claude.json into the affected config dir's .claude.json.

View original on GitHub ↗