[BUG] Termux: Background tasks fail with malformed path - HOME sanitization breaks on deep paths
Claude Code Termux Issue: EACCES Permission Denied with Malformed Tasks Path
Summary
Claude Code fails on Termux (Android ARM64) with a permission error and malformed file path when running background tasks. The path construction naively sanitizes the HOME directory by replacing slashes with dashes, creating an invalid path.
Error Message
Error: EACCES: permission denied, mkdir '/tmp/claude/-data-data-com-termux-files-home/tasks'
at mkdirSync (node:fs:1325:26)
at ZdB (file:///data/data/com.termux/files/usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:1018:8797)
at bu (file:///data/data/com.termux/files/usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:1018:9430)
at Object.spawn (file:///data/data/com.termux/files/usr/bin/node:25.2.1)
Environment
| Variable | Value |
|----------|-------|
| Platform | Termux on Android ARM64 |
| OS | Linux 5.15.178-android13 |
| Node.js | v25.2.1 |
| NPM | 11.6.2 |
| Claude Code | 2.0.76 (latest) |
| Shell | /bin/bash (Termux) |
| HOME | /data/data/com.termux/files/home |
| PWD | /data/data/com.termux/files/home |
| TMPDIR | /data/data/com.termux/files/usr/tmp |
Reproduction Steps
- Install Claude Code in Termux
- Run any command with
run_in_background: true - Or execute a background shell task via Bash tool
Expected: Background task created successfully in /tmp/claude/tasks/
Actual: EACCES: permission denied with malformed path
Root Cause Analysis
Claude Code constructs the tasks directory path by sanitizing the HOME environment variable:
Input: /data/data/com.termux/files/home
Logic: Replace all "/" with "-"
Result: -data-data-com-termux-files-home
Path: /tmp/claude/-data-data-com-termux-files-home/tasks
This naive sanitization works on standard Linux systems (/home/user → -home-user) but fails on Termux's deeply nested path structure.
Why This Happens
The code likely attempts to create a unique, filesystem-safe directory name from the HOME path to isolate tasks per user. The simple replace(/\//g, '-') approach:
- ✅ Works:
/home/alice→/tmp/claude/-home-alice/ - ❌ Fails:
/data/data/com.termux/files/home→/tmp/claude/-data-data-com-termux-files-home/
Additionally, /tmp in Termux has restrictive permissions, making directory creation challenging.
Impact
- Severity: High
- Platforms Affected: Termux (Android)
- Features Blocked: Background task execution
- Users Affected: Any Claude Code user on Termux
Recommended Fixes
Option 1: Use XDG Base Directory (Recommended)
Follow XDG Base Directory Specification:
const path = require('path');
const tasksDir = path.join(
process.env.XDG_CACHE_HOME || path.join(process.env.HOME, '.cache'),
'claude',
'tasks'
);
// Result: ~/.cache/claude/tasks
Advantages:
- ✅ Cross-platform compatible (Linux, macOS, Windows, Termux)
- ✅ Follows standard conventions
- ✅ Works with deeply nested paths
- ✅ Persists between sessions
- ✅ No special permissions needed
Option 2: Use Hash Instead of Path Replacement
const crypto = require('crypto');
const homehash = crypto
.createHash('sha256')
.update(process.env.HOME)
.digest('hex')
.substring(0, 12);
const tasksDir = path.join(os.tmpdir(), 'claude', homehash, 'tasks');
// Result: /tmp/claude/a1b2c3d4e5f6/tasks
Advantages:
- ✅ Always produces valid directory names
- ✅ Still uses /tmp for temporary data
- ✅ Unique per user
Option 3: Respect $TMPDIR
const tasksDir = path.join(process.env.TMPDIR || '/tmp', 'claude', 'tasks');
Advantages:
- ✅ Respects user's temporary directory preference
- ✅ Simple fix
Workaround for Users (Immediate)
Until this is fixed, Termux users can work around the issue by setting TMPDIR:
# Create user temp directory
mkdir -p ~/tmp
# Run Claude Code with custom TMPDIR
TMPDIR=~/tmp claude-code [command]
# Or add to ~/.bashrc
export TMPDIR=~/tmp
Additional Notes
- This issue is specific to the path construction logic in Claude Code's task spawning system
- The error is reproducible consistently on Termux with any background operation
- The
/tmp/claude/directory creation is the first point of failure; permission handling could also be improved
Related Issues
None found in GitHub issue tracker (searched: "EACCES", "tmp/claude", "Termux", "permission denied")
Suggested PR Changes
The fix should be implemented in the CLI's file path construction logic (currently at line 1018 in cli.js based on stack trace):
// BEFORE (problematic):
const taskDir = `/tmp/claude/${process.env.HOME.replace(/\//g, '-')}/tasks`;
// AFTER (recommended):
const path = require('path');
const taskDir = path.join(
process.env.XDG_CACHE_HOME || path.join(process.env.HOME, '.cache'),
'claude',
'tasks'
);
---
Reporter: Termux User on Android ARM64 (Accessibility: TalkBack)
Date: 2025-12-30
Severity: High (Blocks background task execution on Termux)
This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗