Nested claude CLI deletes parent session's Bash tool output capture file in /tmp/claude-*

Resolved 💬 2 comments Opened Mar 4, 2026 by BeeGass Closed Apr 1, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

When running any claude CLI subcommand (e.g. claude plugin list, claude mcp list, claude doctor) inside a Claude Code session's Bash tool, the nested claude process deletes the parent session's output capture file, causing all stdout/stderr to be silently lost.

The command itself succeeds and produces output -- it just never reaches the user.

Environment

  • Claude Code versions tested: 2.1.66 (latest), 2.1.50 (stable) -- both affected
  • OS: Ubuntu 25.10 (Linux 6.17.0-14-generic)
  • Shell: zsh

Steps to Reproduce

  1. Start a Claude Code session
  2. Ask Claude to run claude plugin list via the Bash tool
  3. Observe: Tool ran without output or errors -- no output displayed
  4. Run the same command in a terminal outside Claude Code -- works perfectly

Root Cause

The Bash tool captures command output by redirecting stdout/stderr to a file at:

/tmp/claude-<uid>/<workspace>/tasks/<id>.output

The nested claude process runs session/temp file cleanup at startup, which deletes files in this shared /tmp/claude-<uid>/ directory tree -- including the parent session's active output capture file.

Proof via File Descriptor Tracing

#!/bin/bash
# Run inside Claude Code Bash tool -- trace output to fd 3
OUTFILE=$(readlink /proc/$$/fd/1)
exec 3>/tmp/trace.txt

echo "Output file: $OUTFILE" >&3
echo "Before: size=$(stat -c%s "$OUTFILE")" >&3       # 14 bytes
echo "MARKER_BEFORE"                                    # writes to output file

claude plugin list > /dev/null 2>&1                     # even with output discarded!

echo "After: size=$(stat -c%s "$OUTFILE" 2>/dev/null || echo GONE)" >&3  # GONE
echo "MARKER_AFTER"                                     # writes to deleted fd

# Result: output file deleted, both MARKER_BEFORE and MARKER_AFTER lost

Trace output confirms:

  • Before claude: output file exists, 14 bytes, inode 48465
  • After claude: output file is deleted from the filesystem
  • The tasks directory listing confirms the .output file is removed
  • Even echo after the claude call writes to a dangling fd

Key Observations

  • claude --version works fine (uses a fast-path console.log that returns before cleanup runs)
  • The CLAUDECODE=1 env var is set and the subcommand allowlist correctly permits the command -- the command succeeds
  • File redirect workaround works: claude plugin list --json > /tmp/output.json captures all data correctly (6844 bytes of valid JSON), but the Bash tool itself shows nothing
  • All hooks were disabled during testing to rule them out
  • Tested on both v2.1.66 (latest) and v2.1.50 (stable) -- same behavior

Related Issues

  • #8856 -- Documents /tmp/claude-*-cwd file accumulation (related temp file management)
  • #15700 -- Documents hardcoded /tmp/claude/ path for background tasks
  • #573 (agent-sdk) -- Documents CLAUDECODE=1 subprocess inheritance

Expected Behavior

Nested claude subcommands should not delete files belonging to the parent session. Possible fixes:

  • Skip temp file cleanup entirely when CLAUDECODE=1 (running as nested process)
  • Scope cleanup to only files owned by the current process/session
  • Use a separate namespace for nested process temp files

Workaround

Redirect output to a file outside the tasks directory, then read it:

claude plugin list --json > /tmp/plugins.json 2>&1
cat /tmp/plugins.json

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗