[Bug]: "turn/setPermissionMode failed" masks provider CLI startup death — macOS TCC EPERM kills both Claude and Codex when project is in a protected folder
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
On macOS:
- Have a project inside a TCC-protected folder (
~/Desktop/...,~/Documents/...,~/Downloads/...) - Remove T3 Code's Files-and-Folders permission — or simply delete + re-download the app, which can invalidate the existing grant silently (macOS shows no re-prompt)
- Send any prompt in any thread, with any provider
Expected behavior
- When the provider CLI process exits before/during the control-protocol handshake, the UI error should surface the child's stderr and exit code, not the name of the first RPC that happened to fail against the dead process.
- On macOS, when the spawn fails with
EPERMand the project path is under Desktop/Documents/Downloads, show actionable guidance ("grant T3 Code access in System Settings → Privacy & Security → Files and Folders").
Actual behavior
- Claude threads fail with
Provider turn start failed — turn/setPermissionMode failedand a "Claude runtime stream failed." banner - Codex threads fail with
ProviderAdapterProcessError: ... Codex App Server process exited with code 1 - Neither error mentions the real cause. The truth is only in
~/.t3/userdata/logs/server.trace.ndjson:
[cause]: Error: Claude Code process exited with code 1.
stderr: error: An internal error occurred (EPERM)
The spawned CLI dies instantly on startup (macOS TCC denies file access under the protected folder for child processes of the app), and the first control request (set_permission_mode) fails against a dead process — so the user-facing error blames permission modes. This sends users down entirely the wrong debugging path (reinstalling the app, changing the permission-mode dropdown, etc.), and I suspect some existing reports of this error tag (e.g. #4495) are actually this failure mode misdiagnosed.
Verified during diagnosis: the same pinned CLI binary, run from Terminal in the same project directory, works perfectly — including every set_permission_mode value (default, acceptEdits, plan, bypassPermissions, auto) sent over the stream-json control protocol. The failure only occurs when the CLI is spawned as a child of T3 Code without the folder grant.
Impact
Major degradation or frequent failure
Version or commit
0.0.32
Environment
macOS (Darwin 25.5), T3 Code 0.0.32 desktop app, claude CLI 2.1.223 (SDK-pinned, @anthropic-ai/claude-agent-sdk 0.3.223), codex-cli 0.147.0. Both providers fail identically; both work standalone from Terminal.
Workaround
tccutil reset All com.t3tools.t3code
then relaunch the app and re-grant folder access when prompted. Fixes both providers immediately.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in apps/server by tracing provider CLI startup and the control-protocol handshake, using the server.trace.ndjson example and the macOS protected-folder reproduction. Compare the Claude and Codex startup failures, then verify that a provider exiting with EPERM exposes stderr and its exit code rather than the failed RPC. Done means actionable Files and Folders guidance appears for protected Desktop, Documents, or Downloads paths.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, typescript
- Domain
- backend, desktop, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100