[BUG] Background tasks ignore $TMPDIR and hardcode /tmp/claude/

Open 💬 17 comments Opened Dec 29, 2025 by Butanium

Description

Claude Code's background task system ignores the $TMPDIR environment variable and hardcodes /tmp/claude/ for task management, causing permission denied errors when /tmp is not writable by the user.

Steps to Reproduce

  1. Have $TMPDIR set to a valid, writable directory (e.g., /run/user/$(id -u))
  2. Ensure /tmp is not writable by the current user
  3. Run a background task in Claude Code (e.g., run_in_background: true on a Bash command)

Expected Behavior

Claude Code should respect $TMPDIR and create its task directory there.

Actual Behavior

Claude Code ignores $TMPDIR and attempts to create /tmp/claude/<workspace-path>/tasks, resulting in:

EACCES: permission denied, mkdir '/tmp/claude/-mnt-nw-home-c-dumas-research-libs-nnsight/tasks'

Environment

  • OS: Linux 6.8.0-60-generic (Ubuntu)
  • TMPDIR: /run/user/2011 (set and valid)
  • Claude Code version: Latest

Notes

This is distinct from existing issues like #10194 (TMPDIR pointing to non-existent directory) and #14799 (EXDEV with tmpfs). In this case, $TMPDIR is correctly set to a valid, writable directory, but Claude Code completely ignores it for the background task system.

View original on GitHub ↗

17 Comments

Butanium · 6 months ago

see also https://github.com/anthropics/claude-code/issues/15637 for same issue on a diff platform

salviz · 6 months ago

Additional Finding: Termux Path Sanitization Variant

A related issue has been discovered on Termux (Android) that stems from the same root cause. See #15801.

Termux-Specific Problem: The path sanitization logic (replacing / with -) creates invalid paths on systems with deeply nested HOME directories.

Example:

  • HOME: \/data/data/com.termux/files/home\
  • Sanitized: \-data-data-com-termux-files-home\
  • Invalid Path: \/tmp/claude/-data-data-com-termux-files-home/tasks\

Both issues (#15700 and #15801) would be fixed by using XDG Base Directory Specification (\~/.cache/claude/tasks\) or properly hashing the HOME path instead of character replacement.

Platform: Termux on Android ARM64
Reporter: User with TalkBack accessibility needs

Butanium · 6 months ago

@claude any fix you'd suggest for this?

Lectem · 6 months ago

It seems this propagated to agents, can't run them this morning, most likely due to 2.1.0

andersglindstrom · 6 months ago

To work around this problem, I did this:

:; claude --version
2.1.1 (Claude Code)

This is the version with the bug.

First thing, disable auto update by adding this to ~/.claude/settings.json:

  "env": {
    "DISABLE_AUTOUPDATER": "1"
  }

If you are still on version 2.0.76 you're good.

If you are on 2.1.1 then you also have to do this:

:; npm install @anthropic-ai/claude-code@2.0.76

And then verify:

:; claude --version
2.0.76 (Claude Code)
Butanium · 6 months ago

@andersglindstrom this solution was described in the termux post and worked for me:
sed -i "s|/tmp/claude|/data/data/com.{CUSTOM_TMP_PATH}|g" cli.js

I asked Claude to find cli.js referencing the issue and I have a custom command like this that I run after each update

Lectem · 6 months ago

I can confirm replacing the hardcoded path with a usable one fixed subagents.

Lectem · 6 months ago

2.1.5 seems to have made things worse and patch no longer works.

Butanium · 6 months ago

@Lectem we investigated this and there is now a fix:
The fix is working (directories exist). What exactly is the issue you're experiencing? Can you describe what "doesn't work anymore" means - is there an error message?

Let me also check if there are newer patterns in the code that might need patching:

● Bash(grep -c 'CLAUDE_CODE_TMPDIR' "/mnt/nw/home/c.dumas/.nvm/versions/node/v22.17.0/lib/node_modules/@anthropic-ai/claude-code/cli.js")
⎿ 3

● Good news - newer versions of Claude Code support CLAUDE_CODE_TMPDIR environment variable! Instead of patching the binary, you can now use this cleaner approach:

export CLAUDE_CODE_TMPDIR=/run/user/$(id -u)

Add this to your ~/.bashrc or ~/.zshrc and it should work without needing to patch cli.js after each update.

What specific error are you seeing? That will help me determine if there's another issue at play.

Lectem · 6 months ago

I was getting such messages:

Bash(rm -rf build && CMAKE_C_COMPILER_LAUNCHER=ccache CMAKE_CXX_COMPILER_LAUNCHER=ccache cmake -B build -G Ninja 2>&1 | tail -20) ⎿  Error: EACCES: permission denied, mkdir '/tmp/claude/-data-data-com-termux-files-h ome-code-myproject/tasks'

And the workaround mentioned here https://github.com/anthropics/claude-code/issues/15700#issuecomment-3723281340 would make Claude code freeze after a few seconds. (it could also be another bug of 2.1.5 I guess)

In any case it seems that CLAUDE_CODE_TMPDIR works, this should be documented or set properly to read $TMPDIR by default.

salviz · 6 months ago

Update: Partial Workaround & Root Cause Analysis

Tested Environment Variable Fix (Incomplete):
Setting export TMPDIR="\$HOME/.cache/tmp" in .bashrc partially works for direct commands but does not fix background task execution.

Confirmed Root Cause: Claude Code hardcodes /tmp/claude in the Node.js process itself, not respecting the TMPDIR environment variable even when set globally.

Evidence:

  • ✅ Simple foreground commands execute successfully
  • ❌ Background tasks with run_in_background: true still fail
  • ❌ Long-running operations still fail despite TMPDIR being set

Fix Recommendation:
Replace hardcoded paths with require('os').tmpdir() throughout codebase. This will:

  1. Respect TMPDIR environment variable globally
  2. Use platform-appropriate temp directories (Termux, containers, restricted environments)
  3. Fix background agent execution
andynu · 6 months ago

I work with scientists in a shared computing environment. This bug is causing some collisions for us, too. The CLAUDE_CODE_TMPDIR workaround was effective, but respecting the main TMPDIR would be more idiomatic for the HPC space. Thanks!

salviz · 6 months ago

Verified: Still Failing on v2.1.11 - Background Tasks Non-Functional

Environment

  • Claude Code: 2.1.11 (Latest)
  • Platform: Android 13 (aarch64, Samsung device)
  • OS: Linux 5.15.178-android13-8
  • $TMPDIR Status: NOT respected

Confirmed Issue

Background task system completely broken - same error as reported:

EACCES: permission denied, mkdir '/tmp/claude/-data-data-com-termux-files-home/tasks'

Test Case: Background Task Spawn

Task tool with run_in_background: true

Result: ❌ Fails immediately

Current Status

  • /tmp/claude hardcoding NOT FIXED in v2.1.11
  • Environment variable $TMPDIR still IGNORED
  • No fallback to os.tmpdir() implemented

Impact on Users

  • Cannot use run_in_background: true parameter
  • Agents cannot spawn (they need task directory)
  • Multi-agent workflows impossible on Termux/Android

The update did NOT address this issue. Still waiting for environment variable support.

Butanium · 6 months ago

@salviz CLAUDE_CODE_TMPDIR is the env variable workaround

salviz · 5 months ago

Additional confirmation from Termux user

Same issue here. My configuration:

# ~/.profile
export TMPDIR="$HOME/.cache/tmp"
export CLAUDE_CODE_TMPDIR="$HOME/.claude-tmp"

Both directories exist and are writable. Claude Code ignores both and still tries /tmp/claude/....

Test Results

| Variable | Set | Directory Exists | Respected by Claude Code |
|----------|-----|------------------|--------------------------|
| TMPDIR | ✓ | ✓ | ❌ |
| CLAUDE_CODE_TMPDIR | ✓ | ✓ | ❌ |

Environment

  • Platform: Termux (Android 13)
  • Node.js: v24.13.0
  • Error: EACCES: permission denied, mkdir '/tmp/claude/-data-data-com-termux-files-home/tasks'

This confirms the path is hardcoded in the CLI, not read from environment or os.tmpdir().

Affected Operations

  • All background tasks
  • Agent spawning (Task tool)
  • Any operation using run_in_background

Request

This issue and its 7+ duplicates have been open since late December 2025. Can we get an ETA on when os.tmpdir() support will be added?

---
Reported from Termux (accessibility user)

nbros · 3 months ago

I see the "stale" tag on this issue, but the issue is still very much present in the latest version v2.1.81

andersglindstrom · 3 months ago
I see the "stale" tag on this issue, but the issue is still very much present in the latest version v2.1.81

Try setting CLAUDE_CODE_TMPDIR to something else (in your home directory for example) before you invoke Claude Code. And, inside Claude Code, instruct it to set TMPDIR to CLAUDE_CODE_TMPDIR whenever it invokes bash. This has worked for me. The alternative, if you can be bothered, is to run Claude Code in a Docker container so it has its own private /tmp. Not ideal but it works.