WorktreeCreate hook fails with EPERM for repos under ~/Documents — hook spawned via 'disclaimer' shim loses the app's TCC Documents grant
Environment
- macOS 26.5.1 (build 25F80)
- Claude desktop app 1.11187.4 (Claude Code 2.1.160; bundled
claude2.1.165) - Bundle id
com.anthropic.claudefordesktop - Repo located under a TCC-protected folder:
~/Documents/GitHub/<repo> - A custom
WorktreeCreatehook in.claude/settings.json(the same failure applies to any hook that reads/writes files under~/Documents)
Summary
Creating a worktree fails because the WorktreeCreate hook is launched through /Applications/Claude.app/Contents/Helpers/disclaimer, which makes the hook its own TCC-responsible process instead of inheriting Claude's identity. The disclaimed process has no Documents-folder grant, so every file operation under ~/Documents returns EPERM ("Operation not permitted") — including opening the hook script itself. Granting the Claude app Full Disk Access does not help, because the hook does not run under the app's identity.
Actual error
WorktreeCreate hook failed: bash "$CLAUDE_PROJECT_DIR/.claude/hooks/worktree-create.sh":
shell-init: error retrieving current directory: getcwd: cannot access parent directories: Operation not permitted
bash: /Users/<user>/Documents/GitHub/<repo>/.claude/hooks/worktree-create.sh: Operation not permitted
Adding a cd "$CLAUDE_PROJECT_DIR" && prefix to the hook command produces an extra chdir: error retrieving current directory: getcwd: … line and still fails — confirming it is not a working-directory problem.
Expected
The hook runs with the same file access as the app (which holds the Documents-folder TCC grant).
Reproduction
- Put a repo under
~/Documents(e.g.~/Documents/GitHub/foo). - Configure a
WorktreeCreatehook (or any hook that reads a file under~/Documents). - Create a worktree from the desktop app → hook fails with
EPERM.
Decisive evidence (runnable in Terminal)
# Spawned via Claude's disclaimer shim (how the hook is launched) -> DENIED under ~/Documents:
"/Applications/Claude.app/Contents/Helpers/disclaimer" /bin/sh -c 'ls ~/Documents/GitHub/<repo>/.claude/hooks'
# ls: ...: Operation not permitted
# A normal process -> OK:
/bin/sh -c 'ls ~/Documents/GitHub/<repo>/.claude/hooks' # lists fine
# Same disclaimer shim against a non-protected path -> OK:
"/Applications/Claude.app/Contents/Helpers/disclaimer" /bin/sh -c 'ls /tmp' # lists fine
# The app DOES hold the Documents grant (so the hook clearly is not using the app identity):
sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db \
"select service,client,auth_value from access where client like '%anthropic%';"
# kTCCServiceSystemPolicyDocumentsFolder|com.anthropic.claudefordesktop|2 (2 = allowed)
This is not a stale-cwd bug: a genuinely deleted working directory yields ENOENT ("No such file or directory"), not EPERM.
Impact
Any user whose repos live under ~/Documents, ~/Desktop, or ~/Downloads cannot use WorktreeCreate (or any file-touching) hooks. The raw getcwd / "Operation not permitted" output reads like a generic permissions issue, and the intuitive fix (Full Disk Access for Claude) has no effect — a frustrating dead end.
Suggested fix (any one)
- Don't disclaim TCC responsibility for hook subprocesses — let them inherit the app's identity/grants.
- If disclaiming is required for sandboxing, keep the Claude bundle as the responsible process so its Documents/FDA grant still applies.
- At minimum, detect
EPERMunder a protected folder and surface an actionable message ("Claude can't access files under ~/Documents for this hook — move the repo or grant access") instead of the rawgetcwd/"Operation not permitted" output.
Workaround
Move the repo out of ~/Documents / ~/Desktop / ~/Downloads (e.g. to ~/GitHub), then git worktree repair.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗