Preflight Checklist
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/ if TMPDIR is 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 of TMPDIR
- 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 permissions drwxr-xr-x (755)
- As User B (different user, same group), set environment variables:
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
Preflight Checklist
What's Wrong?
Claude Code fails with EACCES on multi-user systems when /tmp/claude is not writable
Environment
Relevant environment variables:
File system state:
Problem Description
Claude Code attempts to create workspace-specific cache directories in
/tmp/claude/regardless of theTMPDIRenvironment variable setting. When/tmp/claude/is owned by another user with restrictive permissions (755), Claude Code fails with anEACCESpermission error.This is a common scenario on shared computing clusters where:
/tmp/claude/with their default umask (typically 755)Actual Behavior
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:
python main.py configs/config.yamlWhat Should Happen?
Expected Behavior
Claude Code should handle temporary directories in one of these ways:
Option 1: Respect TMPDIR (Preferred)
When
TMPDIRis set, use$TMPDIR/claude/instead of hardcoded/tmp/claude/:Option 2: Graceful fallback
If
/tmp/claude/is not writable, fall back to:$TMPDIR/claude/ifTMPDIRis set$HOME/.cache/claude/as a last resortOption 3: User-specific directories by default
Always use user-specific paths to avoid multi-user conflicts:
Additional Context
Observed behavior:
$TMPDIR/claude/(e.g.,/tmp/user/457296/claude/)/tmp/claude/regardless ofTMPDIRCurrent workarounds:
sudo chmod 1777 /tmp/claude(sticky bit like/tmp)chmod 775 /tmp/claude(if they remember)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:
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
Error Messages/Logs
Steps to Reproduce
Steps to Reproduce
/tmp/claude/with permissionsdrwxr-xr-x(755)/path/to/project)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