Starting a session in Claude Desktop revokes filesystem access from already-running CLI sessions (macOS TCC identity collision)
Summary
On macOS, starting a Claude Code session inside Claude Desktop causes already-running Claude Code CLI sessions to lose read access to their own working tree, if that tree sits in a TCC-protected folder (~/Documents, ~/Desktop, ~/Downloads).
The running session does not fail cleanly. It keeps accepting work while every file read returns EPERM, and git reports fatal: Unable to read current working directory. In my case it burned most of a working session before the cause was found, because nothing in the output points at a permissions problem.
Environment
- macOS 26.5.1 (25F80), Apple silicon
- Claude Code CLI 2.1.227, host terminal has Full Disk Access
- Claude Desktop bundling Claude Code 2.1.229
- Repo at
/Users/<user>/Documents/GitHub/<repo>— inside the TCC-protected Documents folder
Reproduction
- Put a repo in
~/Documents. Give the host terminal Full Disk Access. - Start a Claude Code CLI session there. Confirm file reads work.
- Leave it running. Open Claude Desktop and start a Claude Code session in the same directory.
- Go back to the CLI session. Every read now fails:
cat package.json→Operation not permittedgit rev-parse --abbrev-ref HEAD→fatal: Unable to read current working directory: Operation not permitted- the file-read tool →
EPERM: operation not permitted, open '…'
- Close the Desktop-hosted session in the UI. CLI access returns immediately.
Step 5 restored access while the Desktop helper processes were still alive (verified with ps), so the trigger is the active session, not the process existing.
Evidence
Both binaries are the same TCC principal.
$ codesign -dv ".../Claude/claude-code/2.1.229/claude.app/Contents/MacOS/claude"
Identifier=com.anthropic.claude-code
TeamIdentifier=Q6L2SF6YDW
$ codesign -dv "~/.local/share/claude/ClaudeCode.app/Contents/MacOS/claude"
Identifier=com.anthropic.claude-code
TeamIdentifier=Q6L2SF6YDW
Claude Desktop launches Claude Code through Apple's responsibility-disclaiming helper.
/Applications/Claude.app/Contents/Helpers/disclaimer \
~/Library/Application Support/Claude/claude-code/2.1.229/claude.app/Contents/MacOS/claude …
Disclaiming stops the child inheriting Claude Desktop's TCC attribution, so it becomes responsible for itself — com.anthropic.claude-code, which has no Documents-folder grant. Being non-interactive, it cannot be prompted, so the request is denied.
The denial is scoped to the identity, not the process. The CLI session was covered by its host terminal's grant until the Desktop session created a self-responsible sibling sharing the same identifier. A TCC decision cached against com.anthropic.claude-code would explain why an unrelated, already-running process loses access. I could not read tccd's record to prove this last step — log show returns nothing usable without privileges and the TCC database itself needs Full Disk Access — so treat the caching mechanism as the best-fitting explanation rather than a measured fact. Everything above it is measured.
Ruled out:
- POSIX permissions, ACLs and file flags.
~/Documentsisdrwx------ <user> staffwith the stockgroup:everyone deny deleteACL, identical to~/Desktop, which stayed readable throughout. - Filesystem or mount fault.
staton the denied paths succeeds; onlyopen/readdirfail. That split is characteristic of TCC. - Path aliasing. The firmlink path
/System/Volumes/Data/Users/…is denied identically. - Claude Code's own sandbox. Retrying with the Bash sandbox override produced the same
EPERM. - The host terminal. The affected session ran under a third-party process supervisor, but per the reporter's own observation the same failure occurs with a plain terminal host, and the identity evidence above is host-independent.
Impact
A long-running session silently loses its working tree mid-task and carries on taking instructions. An agent in that state cannot read, test or commit, and the surfaced errors name neither permissions nor the real cause. Anyone keeping a repo in ~/Documents — a common default — hits this the first time they open a Desktop session alongside a CLI one.
Two separate defects
- Cross-session access revocation. A newly started session should not be able to remove filesystem access from sessions already running. Either let Claude Desktop's spawned Claude Code inherit Desktop's TCC responsibility instead of disclaiming to the shared identifier, or isolate the two so one session's evaluation cannot affect another's.
- No diagnosis on failure. When reads against the session's own working directory start returning
EPERM, Claude Code should say so once, clearly, and stop — rather than passing rawerrnoto the model and continuing. A one-line "the working directory has become unreadable; this is usually a macOS privacy grant" would have saved the entire investigation.
Note
Long-lived sessions outlive their binary: my session was still running 2.1.227, which no longer exists on disk (versions/ held 2.1.223, 2.1.232, 2.1.233, 2.1.235). Whatever fix lands should account for several versions sharing one daemon namespace and one signing identity at the same time.
Aside
I hear there are t-shirts. This one cost me a working session and a wrong diagnosis before the cause turned up, so I would like one.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗