Skip to content

Memory leak: Missing cleanup for /tmp/claude-*-cwd working directory tracking files #8856

@Sundeepg98

Description

@Sundeepg98

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

  1. Claude Code generates a random temp file path: let K = \${V}/claude-${F}-cwd``
  2. Appends pwd -P >| ${K} to every Bash command to capture final directory
  3. Reads the file with bq6(K,{encoding:"utf8"}) to update internal cwd
  4. 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

  1. Run any Bash command: ls
  2. Check temp files: ls /tmp/claude-*-cwd
  3. Observe new file created but not deleted
  4. Repeat and watch accumulation

Why This Design Exists

The temp file approach is actually clever and necessary:

  • Tracks cd commands 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

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions