You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: Claude instances with empty vs. "~/.claude" CLAUDE_CONFIG_DIR get different continuation group keys #12616
I searched existing issues and did not find a duplicate.
I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
On one environment, keep the default Claude instance with the CLAUDE_CONFIG_DIR field empty (the UI shows ~/.claude as placeholder).
Add a second Claude instance and enter ~/.claude explicitly in the CLAUDE_CONFIG_DIR field. Authenticate it with a different account via the CLAUDE_CODE_OAUTH_TOKEN environment variable.
Start a thread on the default instance and send a message.
Open the model picker and try to switch to the second instance.
Expected behavior
Both instances use the same Claude config directory (~/.claude), so they should share a continuation group and switching mid-thread should be allowed.
Actual behavior
The second instance is disabled with " is unavailable in this thread. Start a new thread to switch providers."
makeClaudeContinuationGroupKey resolves an empty homePath to os.homedir() instead of the directory Claude actually uses:
empty -> claude:home:/home/<user>
~/.claude -> claude:home:/home/<user>/.claude
The keys differ even though the session storage is identical. Since the empty field displays ~/.claude as placeholder, the two settings look identical in the UI (see screenshots).
Impact
Minor bug or occasional failure
Version or commit
No response
Environment
No response
Logs or stack traces
Clear the CLAUDE_CONFIG_DIR field on the second instance (or enter `~/.claude` explicitly on both) so both resolve to the same key. Switching works afterwards.
Confirmed. This is a real server-side key mismatch, not a model-picker bug.
makeClaudeContinuationGroupKey is built from resolveClaudeHomePath in apps/server/src/provider/Drivers/ClaudeHome.ts. An empty homePath resolves to os.homedir(), while ~/.claude resolves to os.homedir() + "/.claude". Those become different continuation groups:
empty → claude:home:/home/<user>
~/.claude → claude:home:/home/<user>/.claude
The CLI does not use those two paths as different config dirs. When homePath is empty, makeClaudeEnvironment leaves CLAUDE_CONFIG_DIR unset, so Claude Code uses its default (~/.claude) — the same directory an explicit ~/.claude setting points at. The settings field also shows ~/.claude as the placeholder (packages/contracts/src/settings.ts), so the two configs look identical in the UI.
The picker then locks the thread to the first instance’s group (ModelPickerContent / lockedContinuationGroupKey) and disables the other instance with “unavailable in this thread…”.
This empty-path default is leftover from when the field overrode HOME (#2277). #4017 switched the runtime env to CLAUDE_CONFIG_DIR and updated the placeholder, but did not change the continuation-key default. Skills, usage, and session scanning already treat empty as ~/.claude (then inherited CLAUDE_CONFIG_DIR); Codex already treats empty as ~/.codex. ClaudeHome.test.ts still asserts the old homedir() key.
Workaround: leave CLAUDE_CONFIG_DIR empty on both instances, or enter ~/.claude on both.
Fix: make resolveClaudeHomePath (or the continuation-key helper) use the same resolution as resolveClaudeConfigDirPath in ClaudeSkills.ts: configured path, else inherited CLAUDE_CONFIG_DIR, else path.join(os.homedir(), ".claude"). Update the ClaudeHome unit test that currently expects claude:home:${homedir()}.
Activity
juliusmarminge commentedon Sep 19, 2026
Confirmed. This is a real server-side key mismatch, not a model-picker bug.
makeClaudeContinuationGroupKeyis built fromresolveClaudeHomePathinapps/server/src/provider/Drivers/ClaudeHome.ts. An emptyhomePathresolves toos.homedir(), while~/.clauderesolves toos.homedir() + "/.claude". Those become different continuation groups:claude:home:/home/<user>~/.claude→claude:home:/home/<user>/.claudeThe CLI does not use those two paths as different config dirs. When
homePathis empty,makeClaudeEnvironmentleavesCLAUDE_CONFIG_DIRunset, so Claude Code uses its default (~/.claude) — the same directory an explicit~/.claudesetting points at. The settings field also shows~/.claudeas the placeholder (packages/contracts/src/settings.ts), so the two configs look identical in the UI.The picker then locks the thread to the first instance’s group (
ModelPickerContent/lockedContinuationGroupKey) and disables the other instance with “unavailable in this thread…”.This empty-path default is leftover from when the field overrode
HOME(#2277). #4017 switched the runtime env toCLAUDE_CONFIG_DIRand updated the placeholder, but did not change the continuation-key default. Skills, usage, and session scanning already treat empty as~/.claude(then inheritedCLAUDE_CONFIG_DIR); Codex already treats empty as~/.codex.ClaudeHome.test.tsstill asserts the oldhomedir()key.Workaround: leave
CLAUDE_CONFIG_DIRempty on both instances, or enter~/.claudeon both.Fix: make
resolveClaudeHomePath(or the continuation-key helper) use the same resolution asresolveClaudeConfigDirPathinClaudeSkills.ts: configured path, else inheritedCLAUDE_CONFIG_DIR, elsepath.join(os.homedir(), ".claude"). Update the ClaudeHome unit test that currently expectsclaude:home:${homedir()}.cestercian commentedon Sep 19, 2026
Taking this — will normalize empty vs
~/.claudeCLAUDE_CONFIG_DIRso continuation group keys match.