-
Notifications
You must be signed in to change notification settings - Fork 17.5k
Memory leak: Missing cleanup for /tmp/claude-*-cwd working directory tracking files #8856
Description
Bug Description
Claude Code creates temporary files to track working directory changes across Bash command executions but never deletes them, causing accumulation of /tmp/claude-*-cwd files.
Environment
- Claude Code Version: 2.0.1
- OS: Linux (WSL2)
- Node Version: (System default)
The Problem
Every Bash tool invocation creates a temporary file at /tmp/claude-{random-4-hex}-cwd to track the working directory after command execution. These files are never cleaned up, leading to accumulation.
Evidence
- Observed: 174 files accumulated in one day of usage
- Pattern: Each file is 22 bytes containing the working directory path
- Debug log: Shows 2,018 Bash invocations over 4 days
- Only cleanup: systemd-tmpfiles-clean removes them daily at 07:15
Root Cause Analysis
Location in Code
File: /usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js
The issue is in the lq6 function (around line 1520 in the minified code):
// Current implementation (BUG - no cleanup):
P.result.then(async(k)=>{
if(k&&!Y&&!k.backgroundTaskId)try{
j$(bq6(K,{encoding:"utf8"}).trim(),M) // Reads file but never deletes it
}catch{
B1("tengu_shell_set_cwd",{success:!1})
}
})The Mechanism
- Claude Code generates a random temp file path:
let K = \${V}/claude-${F}-cwd`` - Appends
pwd -P >| ${K}to every Bash command to capture final directory - Reads the file with
bq6(K,{encoding:"utf8"})to update internal cwd -
Missing step: Never calls
unlinkSync(K)to delete the file
The Fix
Add cleanup immediately after reading the file:
// Fixed implementation:
P.result.then(async(k)=>{
if(k&&!Y&&!k.backgroundTaskId)try{
let cwdContent=bq6(K,{encoding:"utf8"}).trim();
try{C1().unlinkSync(K)}catch{}; // <- Add this line
j$(cwdContent,M)
}catch{
B1("tengu_shell_set_cwd",{success:!1})
}
})Verification
I applied this fix locally and confirmed:
- Files are now created and immediately deleted after use
- Working directory tracking continues to function correctly
- No accumulation even after running 15+ commands in succession
Impact
- Resource leak: Accumulates filesystem entries (500+ files/day for heavy users)
- Privacy concern: Working directory paths persist in /tmp
- Disk usage: While minimal (22 bytes each), it's unnecessary accumulation
Reproduction Steps
- Run any Bash command:
ls - Check temp files:
ls /tmp/claude-*-cwd - Observe new file created but not deleted
- Repeat and watch accumulation
Why This Design Exists
The temp file approach is actually clever and necessary:
- Tracks
cdcommands across subprocess isolation - Doesn't pollute stdout with pwd output
- Works reliably across all shell types
- The implementation is 95% correct, just missing the cleanup step
Recommendation
This is a simple one-line fix that should be included in the next Claude Code release. The temp file mechanism itself is sound and necessary for stateful directory navigation in a stateless subprocess model.
Additional Notes
- The fix has been tested and verified locally
- No side effects observed
- This affects all Claude Code users on Unix-like systems