[BUG] Desktop: switching organization on ONE account drops running Code sessions — session records are org-scoped but ~/.claude.json and the live connection are not

Status Open
Reported on v2.1.270
Maintainer reply None cached
Activity 3 comments · opened Sep 15, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

Every existing report in this area is about switching between accounts. This is the single-account case: one login holding seats on several organizations, switched with the org picker in the account menu. It is not covered by the multi-account requests, and it behaves worse, because nothing in the UI suggests an org switch should be disruptive at all.

Switching organization while a Claude Code session is running in the Desktop Code tab drops that session. The sidebar empties, the running session stops producing output, and there is no message saying why. Switching back restores the sidebar, but a task that was mid-flight has to be re-driven.

The on-disk shape explains it. Session records are keyed by account and organization:

~/Library/Application Support/Claude/claude-code-sessions/<accountUuid>/<orgUuid>/local_<sessionId>.json

On this machine that is one account with three org directories under it, holding roughly 240, 4 and 2 session records respectively. Same accountUuid, same email, three orgs.

Transcripts are not keyed that way. ~/.claude/projects/ is flat and shared across all three orgs (168 project directories, no account or org segment anywhere in the path).

So the record lookup is org-scoped while the data it points at is not, and ~/.claude.json — which holds the single active organizationUuid that every Claude Code process on that config dir reads — is rewritten in place with nothing reconciling the sessions already running against it.

This is the same root cause as the account-switch report in 85294, reached through the org picker rather than through sign-out/sign-in, and the observable effect matches 92813.

What Should Happen?

Either of these would fix the practical problem:

  1. A running session keeps the organization it started on for its lifetime, and an org switch only changes what new sessions bind to. The session is already single-org by construction — there is no reason its binding has to be read live from a mutable global field.
  2. Failing that, the app should say what happened. A switch that silently stops work in another tab is indistinguishable from a crash or a hang.

A per-session or per-window org pin would solve it outright. Today there is nothing: no flag, no env var, no settings key. forceLoginOrgUUID only restricts which org a login may belong to, it does not pin a session.

Steps to Reproduce

  1. Sign in to an account that holds seats on two or more organizations.
  2. In the Desktop Code tab, start a long-running task on org A.
  3. While it is still working, switch to org B in the account menu.
  4. The sidebar empties and the task stops producing output.
  5. Switch back to org A. The sidebar returns.

Environment

  • Claude Desktop 1.52386.6
  • Claude Code 2.1.270 (bundled, ~/Library/Application Support/Claude/claude-code/)
  • macOS 27.0 (26A428), Apple silicon
  • One account, three organizations (one Enterprise, two Team)

Workaround

CLAUDE_CONFIG_DIR relocates .claude.json itself, so a second config dir gets its own login and its own active org. Desktop does not read that variable, but the Claude Code process it spawns inherits it, so launching the Desktop binary directly with it set gives a genuinely independent window:

CLAUDE_CONFIG_DIR=~/.claude-second /Applications/Claude.app/Contents/MacOS/Claude --user-data-dir=~/.claude-second-desktop

Never through open — launchd strips the environment and you silently get the default profile back.

Two caveats worth recording, because both cost me time:

  • --user-data-dir alone does not isolate the organization. It gives the second instance its own cookies, local storage and oauth token cache, but ~/.claude.json lives in $HOME and is untouched, so both windows still follow each other's org switches. Anyone reporting that this trick works is probably not switching orgs in the second window.
  • CLAUDE_CONFIG_DIR replaces ~/.claude/settings.json rather than merging it. A profile made by hand therefore has no settings at all — no hooks, no agents, and no OpenTelemetry block — and nothing anywhere says so. For a team on managed telemetry that means the second profile reports nothing while looking completely normal.

The keychain half of this already works: credentials are namespaced as Claude Code-credentials-<first 8 of sha256(CLAUDE_CONFIG_DIR)>, so the profiles genuinely do not fight over tokens. That fix shipped and is confirmed in 20553. The config-dir side is what still has no story for the app.

Related

  • 85294 — same root cause, reached via account switch; has the on-disk evidence for the renderer-state half
  • 92813 — matching symptom, tasks pause on the other account until you switch back
  • 74662 — sessions hidden rather than lost after a switch
  • 18435 — the multi-account request this is adjacent to but not the same as; that one wants several accounts, this one is a single account whose own orgs interfere with each other

View original on GitHub ↗

3 Comments

wjames111 · 21 days ago

This tool may be worth looking at. It combines your sessions across different accounts.

schneidermilanistvan-hash · 4 days ago

Same setup here (one login, personal + Team workspace). Two things that may help others while this is open:

  1. Help → "Import Claude Code CLI Sessions…" can't bring these sessions over: it skips any session id that any workspace folder of the account already lists (archived and deleted ones included), which is why it reports nothing.
  2. claude://resume?session=<cliSessionId> (the URL behind claude --desktop --resume) does import a session into the currently selected org without touching the other org's record.

Sidebar folders are per org too, in claude_desktop_config.json under preferences.epitaxyPrefs["dframe-group-scopes"]["<accountUuid>/<orgUuid>"], and desktop scheduled tasks only fire in the active org. Write-up + script: https://github.com/schneidermilanistvan-hash/claude-code-account-switch-recovery (unofficial).

sly321-pixel · 2 days ago

Same single-account setup here (Team + personal on one login), on Windows (Store/MSIX build) and macOS. Two things not mentioned above that cost me time, in case they help others:

  1. MSIX virtualization on Windows. With the Store build, the real data lives in %LOCALAPPDATA%\Packages\Claude_<id>\LocalCache\Roaming\Claude\claude-code-sessions. Files written to %APPDATA% / %LOCALAPPDATA% from inside the app (e.g. by a script launched from a Code-tab session) are redirected into the package's LocalCache, so a Task Scheduler job running outside the package won't see them. Use the Packages path explicitly; fsutil file queryfileid confirms both paths resolve to the same file.
  2. Switching org reloads that org's sidebar. Copying local_<id>.json byte-for-byte into the other org's folder is enough (transcripts are already shared). The session shows up as soon as you switch to that org in the account menu, no restart needed. Once you continue it there, the app rewrites the record with that org's connectors.

Rules I'm using for a two-way sync across 4 machines (~180 sessions): copy byte-for-byte, never re-serialize; while the app is running only add files, and defer overwrites until it's fully quit; never copy deleted_* markers or scheduled-tasks.json, and never re-add a record that was removed on one side; if both sides changed, newest file wins (only sidebar metadata is at stake). Also set cleanupPeriodDays: the 30-day default deletes transcripts and leaves empty sidebar entries.

A native "show sessions from all orgs of this account" option would make all of this unnecessary.