[BUG] Bash sandbox: TCC attribution fails for the live claude process (stale audit token), Documents access lost until TCC toggle
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?
Bash sandbox loses macOS Documents-folder access mid-session; only a TCC toggle restores it
Environment
- Claude Code 2.1.248, installed via npm (
~/.nvm/versions/node/v22.22.2/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe), Node v22.22.2 - macOS 15.7.7 (24G720)
- Terminal: Ghostty 1.3.1, which holds the "Files and Folders -> Documents Folder" grant
- Project directory under
~/Documents/...(a TCC-protected folder) - Bash sandbox enabled (default)
What happens
Several times per session, every file access inside the project directory starts failing with Operation not permitted -- from Bash commands, from uv run python, and from the Read tool (which runs in the main Claude Code process, not in a shell). The first symptom is usually Current directory does not exist from a command that includes a cd into the project, then EPERM on everything under ~/Documents. It never recovers on its own. The only fix is to open System Settings -> Privacy & Security -> Files and Folders and toggle Ghostty's "Documents Folder" switch off and on. It happened five times on 2026-08-27 (10:19, 10:26, 10:28, 17:32, 17:42), all within one Claude Code process (pid 51837, started 09:11).
Nothing in the project changed permissions (owner uid 501, mode unchanged), and Ghostty's TCC record for the Documents folder was NOT modified between the user's toggles -- the only writes to that record all day are the toggles themselves (10:26, 11:48, 17:42).
Evidence (unified log, log show --info --predicate 'process == "tccd" OR process == "sandboxd"')
The same sequence every time. This is the 17:32:51 occurrence, trimmed:
17:32:51 sandboxd: (TCC) SEND: 0/7 synchronous to com.apple.tccd: request: msgID=373.2347,
function=TCCAccessRequest, service=kTCCServiceSystemPolicyDocumentsFolder,
17:32:51 tccd: REQUEST: tccd_uid=501, sender_pid=373, sender_uid=0, sender_auid=-1,
function=TCCAccessRequest, msgID=373.2347
17:32:51 tccd: REQUEST_MSG: msgID=373.2347, msg={
service="kTCCServiceSystemPolicyDocumentsFolder"
TCC_MSG_REQUEST_AUTHORIZATION_SUBJECT_CREDENTIAL_DICTIONARY_KEY={
TCCD_MSG_CREDENTIAL_AUTHENTICATOR_TYPE_KEY=1 (0x1)
TCCD_MSG_CREDENTIAL_AUTHENTICATOR_AUDIT_TOKEN_KEY={pid:51837, auid:501, euid:501}
}
}
17:32:51 tccd: proc_pidpath_audittoken() failed from PID[51837]: (#3) No such process
17:32:51 tccd: Failed to build 'accessingProcess' from indirect_object_token in message from
<TCCDProcess: identifier=com.apple.sandboxd, pid=373, auid=0, euid=0,
binary_path=/usr/libexec/sandboxd>
17:32:51 tccd: REPLY_MSG: msg={
auth_error_string="Failed to create Attribution Chain from message."
auth_value=0 (0x0)
auth_error_code=5 (0x5)
result=false
auth_reason=1 (0x1)
}
17:32:51 sandboxd: tcc_server_message_request_authorization(kTCCServiceSystemPolicyDocumentsFolder)
failed: Error Domain=kTCCErrorDomain Code=5 "server error: Failed to create Attribution
Chain from message."
17:32:51 sandboxd: kTCCServiceSystemPolicyDocumentsFolder denied by TCC for claude.exe
Points to note:
- The audit token names pid 51837. That process is alive -- it is the Claude Code process itself:
ps -p 51837->claude --name ... (started Thu Aug 27 09:11:14 2026). Yet tccd'sproc_pidpath_audittoken()returns "No such process", which is what it returns when the token's pid/pidversion pair no longer matches the live process (a stale token).
- Because tccd cannot attribute the request, it never consults the TCC database at all (
auth_reason=1, error code 5); the request fails on attribution, not on a stored decision.
- sandboxd turns that error into a denial for
claude.exe, and from then on every access from the process is refused -- including the Read tool, which does not go through the sandbox.
- Toggling Ghostty's Documents switch publishes a
TCCDEvent: type=Modifyfor the Documents service, which makes tccd/sandboxd drop the cached denial. That is why the toggle "fixes" it even though the stored grant was never changed. During the seconds the switch is off, the same log shows the expectedAuth Right: Denied (System Set)for Ghostty and adenied by TCC for jqfrom a hook script -- those are consequences of the toggle, not the cause.
- The same
PID[51837]: (#3) No such process->Failed to create Attribution Chainpair appears at each of the five outage times.
The commands that were running when it tripped were ordinary project commands (cd <project> && uv run python ...). uv run spawns short-lived interpreter probes (the log also shows Apple's /usr/bin/python3 being launched from the project directory), which is consistent with the sandbox handing tccd a token for a process that has already changed or gone.
Suggested fix in the sandbox
- When sandboxd's TCC request fails with
kTCCErrorDomain Code=5("Failed to create Attribution Chain"), treat it as an attribution error, not as a policy decision: do not record or cache a denial for the Claude Code process. Retry the request with a fresh audit token of the live process (or of the responsible application), and fall back to the responsible app's existing grant, which in this case is "Allowed".
- Obtain the audit token used for TCC requests at request time from the live main process rather than from a token captured earlier (at sandbox setup or from a transient child). A pid can be reused and a pidversion changes on exec; the "No such process" reply here is the stale-token signature.
- Alternatively, avoid per-command TCC consultation entirely: at session start, when the working directory is inside a TCC-protected folder and the main process already has access, extend that access into the sandbox (a file-read/write sandbox extension for the working directory) so sandboxed children do not re-request Documents access on every command.
Workaround in use
Toggle the terminal app's "Documents Folder" switch in System Settings each time.
Not acceptable workarounds
- Moving the project out of
~/Documentsavoids the TCC check altogether. - Granting Full Disk Access to the terminal.
What Should Happen?
Sandboxed commands and the Read tool should keep access to the project directory for the whole session, as the terminal app's existing "Documents Folder" grant allows. When the sandbox's TCC request fails on attribution (kTCCErrorDomain Code=5, "Failed to create Attribution Chain"), Claude Code should treat that as an error and retry with a valid audit token, or fall back to the responsible app's grant — not cache a denial for the main process. Access should never require the user to toggle a Privacy & Security switch to recover.
Error Messages/Logs
17:32:51 sandboxd: (TCC) SEND: 0/7 synchronous to com.apple.tccd: request: msgID=
373.2347,
function=TCCAccessRequest, service=kTCCServiceSystemPolicyDocumentsFolde
r,
17:32:51 tccd: REQUEST: tccd_uid=501, sender_pid=373, sender_uid=0, sender_auid=-
1,
function=TCCAccessRequest, msgID=373.2347
17:32:51 tccd: REQUEST_MSG: msgID=373.2347, msg={
service="kTCCServiceSystemPolicyDocumentsFolder"
TCC_MSG_REQUEST_AUTHORIZATION_SUBJECT_CREDENTIAL_DICTIONARY_KEY={
TCCD_MSG_CREDENTIAL_AUTHENTICATOR_TYPE_KEY=1 (0x1)
TCCD_MSG_CREDENTIAL_AUTHENTICATOR_AUDIT_TOKEN_KEY={pid:51837, au
id:501, euid:501}
}
}
17:32:51 tccd: proc_pidpath_audittoken() failed from PID[51837]: (#3) No such pro
cess
17:32:51 tccd: Failed to build 'accessingProcess' from indirect_object_token in m
essage from
<TCCDProcess: identifier=com.apple.sandboxd, pid=373, auid=0, euid=0,
binary_path=/usr/libexec/sandboxd>
17:32:51 tccd: REPLY_MSG: msg={
auth_error_string="Failed to create Attribution Chain from message."
auth_value=0 (0x0)
auth_error_code=5 (0x5)
result=false
auth_reason=1 (0x1)
}
17:32:51 sandboxd: tcc_server_message_request_authorization(kTCCServiceSystemPoli
cyDocumentsFolder)
failed: Error Domain=kTCCErrorDomain Code=5 "server error: Failed to cre ate Attribution
Chain from message."
17:32:51 sandboxd: kTCCServiceSystemPolicyDocumentsFolder denied by TCC for claude.exe
Steps to Reproduce
Several times per session, every file access inside the project directory starts failing with Operation not permitted -- from Bash commands, from uv run python, and from the Read tool (which runs in the main Claude Code process, not in a shell). The first symptom is usually Current directory does not exist from a command that includes a cd into the project, then EPERM on everything under ~/Documents. It never recovers on its own. The only fix is to open System Settings -> Privacy & Security -> Files and Folders and toggle Ghostty's "Documents Folder" switch off and on. It happened five times on 2026-08-27 (10:19, 10:26, 10:28, 17:32, 17:42), all within one Claude Code process (pid 51837, started 09:11).
Nothing in the project changed permissions (owner uid 501, mode unchanged), and Ghostty's TCC record for the Documents folder was NOT modified between the user's toggles -- the only writes to that record all day are the toggles themselves (10:26, 11:48, 17:42).
Claude Model
Other
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.248 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Other
Additional Information
_No response_
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Is this a bug you will investigate?
Reproduced on Claude Code 2.1.263 (latest as of Sun, 06 Sep 2026), macOS Darwin 24.6.0, Ghostty, npm install, Bash sandbox on, project under
~/Documents.Trigger this time was identifiable. A Bash command did
cdinto a session-scratchpad directory under/private/tmp/claude-501/...to run LibreOffice, and a later command deleted that directory. The persistent shell was left in a deleted cwd. From then on:python3scripts) failed withFatal Python error: error evaluating path ... OSError: failed to make path absoluteandCurrent directory does not exist, reported as a non-blocking hook error.~/Documents/<project>returnedOperation not permitted: from sandboxed Bash, from Bash with the sandbox disabled, and from the Read tool in the main process (EPERM: operation not permitted, open ...). Paths outside~/Documentsstayed readable.So a shell left in a nonexistent cwd appears to be one way to hit the attribution failure. Noting that the only "merged" item on this issue's timeline is a third-party repository's docs PR citing this issue, not a Claude Code change; nothing in the 2.1.249 to 2.1.263 changelog covers this.
Update: Docker confirms TCC is the root cause, not sandbox logic
I spent a session trying to move Claude Code into a Docker container (OrbStack, Linux, project mounted via VirtioFS) specifically to avoid this bug. It works — the TCC attribution failure cannot trigger inside a container because VirtioFS bypasses TCC entirely.
But Docker is not a viable workaround. The platform split (Linux vs macOS) means the Python venv built for macOS doesn't work inside the container. Maintaining two venvs per project defeats the purpose. I abandoned the approach.
This confirms the bug is purely a TCC/sandboxd interaction — nothing about Claude Code's own sandbox logic or permission system. The failure path is:
uv runinterpreter probe, or a shell left in a deleted cwd)proc_pidpath_audittoken() ... (#3) No such process→ error code 5 ("Failed to create Attribution Chain")Impact
blockReadsOutsideWorkingDirectories makes the prompting worse
Setting
blockReadsOutsideWorkingDirectories: true— the recommended way to keep Claude inside the project — triggers a permission prompt on every compound Bash command. Pipes, subshells, variable expansion, PIPESTATUS checks — anything the static analyzer can't fully parse gets flagged as "Contains expansion; under the read block ... a command the shell parser cannot analyze asks the person." This is most Bash commands in practice.So the two mitigations fight each other:
blockReadsOutsideWorkingDirectories, Claude can read anywhere on the machine.autoAllowBashIfSandboxedwould fix the prompts, but enabling the sandbox risks increasing TCC failures.There is no configuration that gives me "stay inside the project, don't ask me about it, and don't break" on macOS with a ~/Documents project.
Why this matters now
Four months ago I didn't worry much about Claude staying inside the project directory. With each model upgrade, the behavior has gotten more aggressive. Claude now reads and writes files outside the project, modifies shell configs, and runs commands with side effects beyond the working directory — unless actively restrained.
So I went to restrain it, and found there's no working configuration on macOS:
blockReadsOutsideWorkingDirectoriescreates a wall of permission prompts on normal commandsThe models are getting more capable and more autonomous, but the guardrails haven't kept up. I have no way to tell Claude "work freely inside this directory, hard stop at the boundary" on a Mac with projects in ~/Documents — which is where macOS expects users to put their work.
Related
Ask
Can someone from the team acknowledge this cluster and say whether it's being investigated? The suggested fixes from the original report still stand: