macOS: Claude Code's .local/share/claude/versions/<version> install layout triggers TCC prompt churn on every update

Resolved 💬 3 comments Opened Apr 22, 2026 by orendi84 Closed Apr 26, 2026

Summary

Claude Code CLI on macOS installs each version to a new versioned directory and updates the ~/.local/bin/claude symlink to point at it. In observed TCC rows, the client is recorded as the versioned real path (e.g. /Users/<me>/.local/share/claude/versions/2.1.117) rather than the symlink path (~/.local/bin/claude). Each version therefore shows up in TCC as a separate path-identified client, and prior grants do not carry forward - the user is re-prompted on next access to any previously-granted Files & Folders or File Provider resource after each update.

In the observed window on my machine (2026-03-20 to 2026-04-22), Claude Code updated 17 times in 33 days (~1 update per 2 days), so the re-prompt cycle is chronic.

Reported from a single long-lived user account; I have not repro'd on a fresh user or VM.

Environment

  • Claude Code CLI: 2.1.117 (latest observed on this machine as of 2026-04-22) through 2.1.80 (first version recorded in TCC on this machine on 2026-03-20)
  • Install range observed: 2026-03-20 to 2026-04-22 (17 versions in 33 days on this machine, ~1 update per 2 days in that window)
  • macOS: 26.4.1 (Tahoe), Build 25E253, arm64
  • Terminal app invoking claude: Apple Terminal.app > zsh login shell
  • Install / update channel: whatever Claude Code's built-in self-updater uses (I did not install via Homebrew)

Root cause (with artifacts)

Claude Code publishes a stable launcher path via symlink:

$ which claude
/Users/<me>/.local/bin/claude
$ ls -la /Users/<me>/.local/bin/claude
lrwxr-xr-x  1 <me>  staff  55 Apr 22 11:10 /Users/<me>/.local/bin/claude -> /Users/<me>/.local/share/claude/versions/2.1.117

The symlink target is versioned. In observed TCC rows, the client is recorded as the resolved versioned path rather than ~/.local/bin/claude. On every version bump, the symlink target is rewritten to a new versioned path, and new TCC rows are created for that new path.

Evidence from user-scope ~/Library/Application Support/com.apple.TCC/TCC.db before cleanup (1 row per service+client+account, values abbreviated):

service                               | client                                                      | client_type | auth_value
--------------------------------------+-------------------------------------------------------------+-------------+-----------
kTCCServiceFileProviderDomain         | /Users/<me>/.local/share/claude/versions/2.1.114            | 1 (path)    | 2 (allowed)
kTCCServiceFileProviderDomain         | /Users/<me>/.local/share/claude/versions/2.1.116            | 1 (path)    | 2 (allowed)
kTCCServiceFileProviderDomain         | /Users/<me>/.local/share/claude/versions/2.1.117            | 1 (path)    | 2 (allowed)

All entries have client_type = 1 (path). There is no bundle ID or DR-based identity in these rows - Claude Code is being attributed as a path-based, non-bundled client.

Full per-version first-seen dates from system-scope TCC.db (kTCCServiceSystemPolicyAllFiles entries, pre-cleanup):

2.1.80  2026-03-20
2.1.87  2026-04-01
2.1.90  2026-04-02
2.1.91  2026-04-03
2.1.92  2026-04-04
2.1.94  2026-04-08
2.1.96  2026-04-08
2.1.97  2026-04-09
2.1.98  2026-04-09
2.1.101 2026-04-11
2.1.104 2026-04-12
2.1.107 2026-04-14
2.1.109 2026-04-15
2.1.112 2026-04-17
2.1.114 2026-04-19
2.1.116 2026-04-21
2.1.117 2026-04-22

17 distinct TCC clients for the same tool in 33 days.

Reproduction

  1. macOS 14+ (Sonoma and later). Observed on 26.4.1 Tahoe.
  2. Install Claude Code CLI via the standard installer. Confirm symlink layout: ls -la $(which claude) should show a symlink into ~/.local/share/claude/versions/<version>.
  3. Have at least one File Provider domain active (Google Drive, iCloud Drive, Dropbox, etc.).
  4. From Terminal, run a command that reads a file inside that File Provider's data, e.g.:

``
claude -p "list files in ~/Library/CloudStorage/GoogleDrive-<account>/My\ Drive"
`
macOS TCC prompts for Files & Folders access, labeled with the Claude Code version number (e.g.
"2.1.117"`), asking to access "files managed by Google Drive". Click Allow.

  1. Let Claude Code auto-update to the next version (restart terminal session or claude invocation).
  2. Repeat the same command. A fresh TCC prompt fires, labeled with the new version number, for the same File Provider domain.

User impact

  • On every update observed on my machine, prior Files & Folders grants did not carry forward. User is re-prompted on next access for each previously-granted resource (File Provider domains in my case; per-folder grants for Documents/Downloads/Desktop/Network Volumes were also re-prompted on first access under each new version).
  • Users with multiple File Provider domains are hit hardest. My machine: 4 Google Drive accounts + iCloud Drive = 5 File Provider prompts per update minimum, plus per-folder prompts on first access.
  • Orphan TCC rows accumulate in user-scope and system-scope TCC DBs with no supported targeted cleanup. tccutil reset <service> is service-wide (overkill); tccutil reset <service> <bundle_id> does not apply because these rows have no bundle ID. The only supported per-row cleanup is the Privacy & Security UI, row by row, with Touch ID each time. That doesn't prevent recurrence on the next update.

Proposed fix

The invariant TCC needs: the client path TCC records must remain identical across Claude Code updates. Today that path is the resolved versioned target of the ~/.local/bin/claude symlink, so it changes on every update.

What the packaging needs to achieve: readlink -f $(which claude) returns the same path before and after an update. The mechanism (install the real binary at a non-versioned location and replace in place, or other patterns) is Anthropic's call.

Happy to test a prerelease locally if useful.

Out of scope for this issue

  • Cleaning up existing orphan TCC rows on affected users' machines (no safe automated path; documentation is probably the best we can offer).
  • Changes to Claude Code's update cadence. The cadence is not the bug; the packaging-identity pattern is.

Not validated

  • I have not reproduced this on a fresh user account or VM. Apple DTS recommends clean-environment validation for TCC investigations. The above is observed on a single heavily-used macOS 26.4.1 install.
  • I have not inspected Claude Code's code-signing identifier / designated requirement. If macOS ever moves toward DR-based attribution for CLI tools, keeping the signing identity stable across releases would matter too - flagging in case that's relevant to whatever fix you pick.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗