CLI exits 1 with EACCES on /tmp/claude-settings-<hash>.json when multiple macOS users share the host
Summary
On a multi-user macOS host, the Claude Code CLI (bundled with the desktop app, v2.1.128) crashes immediately with exit code 1 whenever any user other than the one who created /tmp/claude-settings-<sha256>.json tries to start a session. The desktop surfaces this as the generic "Claude Code crashed / Claude Code process exited with code 1" banner with no further detail.
Environment
- Claude desktop app: 1.6608.2
- Bundled CLI: 2.1.128
- macOS: Darwin 25.4.0 (arm64)
- Two user accounts on the host (
hectortosa,codesharegrow), each with its own Claude desktop install
Reproduction
- On host with users
AandB, both signed in to Claude on their respective accounts. - Log in as
A, open Claude desktop, start any Claude Code chat. This creates/tmp/claude-settings-44136fa355b3678a.json(content:{}, mode0644, ownerA). - Switch to user
B, open Claude desktop, start any Claude Code chat. - Desktop reports: "Claude Code crashed / Claude Code process exited with code 1".
Root cause
Captured by wrapping claude.app/Contents/MacOS/claude and recording argv, stdin, stderr:
- Desktop spawns CLI with
--settings '{}'(literal empty JSON inline override). - CLI hashes
{}→sha256prefix44136fa355b3678a…and tries to open/tmp/claude-settings-44136fa355b3678a.jsonfor read+write. - File exists, owned by user
A, mode0644. UserBcan read but cannot openO_RDWR. Open fails withEACCES. - CLI emits
Error processing settings: EACCES: permission denied, open '/tmp/claude-settings-44136fa355b3678a.json'on stderr and exits 1. - The desktop's child-process error handler reports only the exit code; the stderr line never reaches the UI.
/tmp has the sticky bit, so user B cannot delete or chmod the file without sudo.
Workaround
sudo rm /tmp/claude-settings-<hash>.json
(or have the owning user delete it; or chmod 666 it). The CLI recreates the file on next launch, owned by whichever user got there first, and the same collision recurs.
Suggested fixes
- Skip the cache entirely when
--settingsis an empty object — there is nothing to cache. - Namespace the cache path by uid, e.g.
/tmp/claude-settings-\$UID-<hash>.json, so users on a shared host don't collide. - Forward the CLI's stderr line to the desktop's crash banner so users see the actual cause instead of a bare exit code.
Diagnostic capture (redacted)
argv:
--output-format stream-json --verbose --input-format stream-json
--effort xhigh --model claude-opus-4-7[1m]
--permission-prompt-tool stdio
--allowedTools mcp__computer-use,mcp__ccd_session__spawn_task,...
--setting-sources=user,project,local --permission-mode auto
--allow-dangerously-skip-permissions --include-partial-messages
--plugin-dir <...> [...]
--replay-user-messages --settings {}
stderr:
Error processing settings: EACCES: permission denied, open '/tmp/claude-settings-44136fa355b3678a.json'
stat of the colliding file:
-rw-r--r-- 1 hectortosa wheel 2 May 11 15:39 /tmp/claude-settings-44136fa355b3678a.json
content: {}This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗