[BUG] Claude Code fails with EACCES on multi-user systems when /tmp/claude is not writable
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?
Claude Code fails with EACCES on multi-user systems when /tmp/claude is not writable
Environment
- OS: Linux (Ubuntu/Debian-based cluster)
- Claude Code Version: 2.1.15 (linux-x64)
- Installation method: VS Code extension
- Environment type: Shared academic/research computing cluster with multiple users
Relevant environment variables:
TMPDIR=/tmp/user/457296
TEMPDIR=/tmp/user/457296
TMP=/tmp/user/457296
TEMP=/tmp/user/457296
File system state:
$ ls -ld /tmp
drwxrwxrwt 34 root root 4096 Jan 22 10:40 /tmp
$ ls -ld /tmp/claude
drwxr-xr-x 9 user2 operator 4096 Jan 15 23:35 /tmp/claude
$ whoami
user1
* user2 is another user. user1 is me. usernames changed for privacy
$ id
uid=457296(user1) gid=37(operator) groups=37(operator)
Problem Description
Claude Code attempts to create workspace-specific cache directories in /tmp/claude/ regardless of the TMPDIR environment variable setting. When /tmp/claude/ is owned by another user with restrictive permissions (755), Claude Code fails with an EACCES permission error.
This is a common scenario on shared computing clusters where:
- Multiple users run Claude Code
- The first user to run Claude Code creates
/tmp/claude/with their default umask (typically 755) - Subsequent users cannot write to this directory even if they're in the same group
Actual Behavior
Error: EACCES: permission denied, mkdir '/tmp/claude/-path-to-project'
The error occurs when Claude Code tries to create a workspace-specific subdirectory in /tmp/claude/ by transforming the working directory path (e.g., /university_cluster/users/user1/projects/project1 → /tmp/claude/-university_cluster-user1-projects-project1).
Examples of failed operations:
- Running Python scripts:
python main.py configs/config.yaml - Spawning Task tool agents
- Any operation requiring workspace cache
What Should Happen?
Expected Behavior
Claude Code should handle temporary directories in one of these ways:
Option 1: Respect TMPDIR (Preferred)
When TMPDIR is set, use $TMPDIR/claude/ instead of hardcoded /tmp/claude/:
TMPDIR=/tmp/user/457296 → Use /tmp/user/457296/claude/-path-to-project
Option 2: Graceful fallback
If /tmp/claude/ is not writable, fall back to:
$TMPDIR/claude/ifTMPDIRis set$HOME/.cache/claude/as a last resort
Option 3: User-specific directories by default
Always use user-specific paths to avoid multi-user conflicts:
/tmp/claude-${USER}/-path-to-project
or
${TMPDIR:-/tmp}/claude/${USER}/-path-to-project
Additional Context
Observed behavior:
- Claude Code successfully creates user-specific session files in
$TMPDIR/claude/(e.g.,/tmp/user/457296/claude/) - However, workspace caches are hardcoded to
/tmp/claude/regardless ofTMPDIR - This inconsistency suggests the codebase uses different temp directory resolution in different modules
Current workarounds:
- Administrator runs:
sudo chmod 1777 /tmp/claude(sticky bit like/tmp) - First user runs:
chmod 775 /tmp/claude(if they remember) - Each user creates their own directory:
mkdir ~/tmp/claude && ln -s ~/tmp/claude /tmp/claude-${USER}(doesn't fix the issue)
All workarounds are suboptimal and require knowledge of the internals.
Suggested Fix
The temp directory resolution should follow this precedence:
function getClaudeWorkspaceTmpDir(workspacePath) {
const baseTmpDir = process.env.TMPDIR ||
process.env.TMP ||
process.env.TEMP ||
'/tmp';
const claudeDir = path.join(baseTmpDir, 'claude');
// Try to use shared directory, fall back to user-specific
try {
fs.mkdirSync(claudeDir, { recursive: true });
} catch (err) {
if (err.code === 'EACCES' || err.code === 'EPERM') {
// Fall back to user-specific directory
const userClaudeDir = path.join(os.homedir(), '.cache', 'claude');
return path.join(userClaudeDir, sanitizeWorkspacePath(workspacePath));
}
throw err;
}
return path.join(claudeDir, sanitizeWorkspacePath(workspacePath));
}
Related Issues
This may be related to general temp directory handling in Claude Code. Consider auditing all temp directory creation to ensure consistent behavior across the codebase.
System Information
$ uname -a
Linux 5.15.0-116-generic
$ ls -la /tmp/user/457296/claude/
# Successfully creates files here - this works correctly
$ env | grep -i tmp
TEMPDIR=/tmp/user/457296
TMPDIR=/tmp/user/457296
TMP=/tmp/user/457296
TEMP=/tmp/user/457296
$ claude --version
2.1.15
---
Error Messages/Logs
Steps to Reproduce
Steps to Reproduce
- On a multi-user Linux system, have User A run Claude Code, which creates
/tmp/claude/with permissionsdrwxr-xr-x(755) - As User B (different user, same group), set environment variables:
``bash``
export TMPDIR=/tmp/user/$(id -u)
export TMP=$TMPDIR
export TEMP=$TMPDIR
- Launch Claude Code from a project directory (e.g.,
/path/to/project) - Attempt to run any command that triggers Claude Code's workspace cache
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.15
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
VS Code integrated terminal
Additional Information
_No response_
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗