[BUG] Claude Desktop's bundled Claude Code overwrites the CLI's 'Claude Code-credentials' keychain item → CLI 'Not logged in' daily (macOS)

Status Open
Reported on v2.1.295
Maintainer reply None cached
Activity 0 comments · opened Oct 14, 2026

Summary

On macOS, the Claude Code that ships inside Claude Desktop (the Code tab, bundled binary 2.1.295) writes to the same keychain item, Claude Code-credentials, as the standalone CLI. When Desktop auto-creates a "scratch" Code session on launch or wake, that process overwrites the CLI's stored OAuth credentials. The next CLI start shows Not logged in · Please run /login.

For me this meant a /login almost every day for two weeks. I never used the Code tab on purpose: Desktop starts at login, opened on the Code tab, and created a scratch session by itself.

Environment

  • macOS 15, Apple silicon
  • Claude Code CLI 2.1.296 (native install), used in the VS Code integrated terminal
  • Claude Desktop 2.31226.1; bundled Claude Code 2.1.295 at ~/Library/Application Support/Claude/claude-code/2.1.295/.../claude.app
  • The CLI and Desktop are signed in to the same personal Pro account

Reproduction (deterministic)

  1. With Claude Desktop running, run /logout in the CLI. The Claude Code-credentials keychain item is deleted.
  2. In Claude Desktop, open the Code tab or start a Code session. A scratch session started on launch has the same effect.
  3. The Claude Code-credentials item is recreated within 1 s of Desktop spawning its bundled CLI ([CCD] learned CLI process group … in ~/Library/Logs/Claude/main.log). The recreated JSON has no claudeAiOauth, only other state.

Observed timestamps, from a watcher polling the item's mdat every 20 s:

10:02:29  CLI /logout → item gone
10:03:02  Desktop: [CCD] learned CLI process group 36575
10:03:02  keychain item recreated (mdat 07:03:02Z), JSON has no claudeAiOauth
10:04:02  CLI /login → full credentials again

How it breaks the CLI in normal use

On a normal day, after the CLI's 8 h access token has expired overnight:

  • 09:26:15: Desktop wakes and obtains its own token.
  • 09:27:41: Desktop auto-creates a scratch Code session (LocalSessions.createScratchWorkspace, Using Claude Code binary at …/2.1.295/…).
  • 09:27:43: the Claude Code-credentials item is rewritten, 2 s after the spawn.
  • 09:41: claude --debug in Terminal starts unauthenticated. The debug log shows [Claude in Chrome] Disabled: OAuth token has no scope accepted by /api/oauth/validate (needs user:profile …) and [claudeai-mcp] Disabled: API-key auth precedence active. The session reports Not logged in.

The token the CLI finds is not the one it stored, and it lacks the scopes the CLI requires. Server-side refresh itself works: the same night the CLI's token refreshed fine.

Correlation

In the user's Desktop data, Code sessions per month were Jul 2, Aug 1, Sep 1 and Oct 25. The first auto-created scratch-* workspace is dated Sep 29, the same day the daily re-logins began. Almost every re-login in that period followed a Desktop launch that auto-created a scratch Code session.

Workaround

Switch Claude Desktop to the Chat tab and relaunch it. Desktop then starts without spawning a Code session, and the CLI login persists.

Expected

Claude Desktop's bundled Claude Code should not read, write or recreate the standalone CLI's Claude Code-credentials item. It should use its own credential store, or its own CLAUDE_CONFIG_DIR-style suffix, especially since Desktop passes its own token to the session anyway. A scratch session that the user never opened should also not touch CLI credentials.

View original on GitHub ↗