Bash tool output suppressed when child process spawns `claude -p`

Resolved 💬 4 comments Opened Feb 25, 2026 by pacaplan Closed Feb 28, 2026

Bug Description

When a command executed via the Bash tool spawns claude -p (pipe mode) as a child process, all stdout and stderr output from the entire Bash session becomes invisible to the Bash tool. This includes output written before the claude -p subprocess is spawned.

Reproduction

Minimal repro — output visible (no claude -p)

Run this via the Bash tool in a Claude Code session:

echo "hello from bash"

Result: "hello from bash" is visible in the tool output. ✅

Minimal repro — output suppressed (with claude -p)

echo "before claude"
claude -p "say hi" --max-turns 1
echo "after claude"

Result: The Bash tool returns zero output. Neither "before claude", the claude response, nor "after claude" are visible. ❌

The data is written to the fds — verified by redirecting stderr to a file and reading it separately:

echo "before" >&2
claude -p "say hi" --max-turns 1 >&2 2>&1
echo "after" >&2

Reading the redirect file confirms all output was produced. The Bash tool simply doesn't return it.

Controls that prove it's specific to claude -p

| Command | Output visible? |
|---------|----------------|
| sleep 3 as child process | ✅ Yes |
| claude --version as child process | ✅ Yes |
| claude -p "say hi" --max-turns 1 as child process | ❌ No |
| echo "before" && claude -p "say hi" --max-turns 1 | ❌ No (even "before" is lost) |

Attempted workarounds (none worked)

  • 2>&1 redirection
  • Piping through cat
  • Wrapping in a subshell
  • Running via node -e or separate script instead of bun
  • stdio: ['pipe', 'pipe', 'pipe'] on child spawn
  • Closing inherited fds 3-255 via shell wrapper, perl, python FD_CLOEXEC
  • detached: true on child spawn
  • Bun.spawn instead of Node child_process.spawn

Workaround that does work

Redirect stderr to a file in the Bash command, then read the file with the Read tool in a separate step:

# Bash tool call
bun my-script.ts 2>/tmp/output.txt

# Then use Read tool on /tmp/output.txt

Root Cause Hypothesis

Investigation of the file descriptors inside the Bash tool session:

  • fd 0: socket
  • fd 1: file (stdout capture)
  • fd 2: file (stderr capture)
  • fd 3: pipe (appears to be the Bash tool's "done" signal/monitoring pipe)
  • fd 4: file

When fd 3 was explicitly closed in the parent process, partial output became visible ("before" appeared), confirming fd 3 is involved in the output capture mechanism. The claude binary in pipe mode likely inherits and interferes with fd 3 (or other control fds), disrupting the Bash tool's ability to collect output from the captured fd 1/fd 2 files.

The claude binary in pipe mode presumably does something special with inherited file descriptors (perhaps scanning/closing/redirecting them) that non-pipe-mode claude --version does not.

Impact

Any tool or workflow that spawns claude -p from within a Bash tool call loses all output visibility. This affects:

  • AI code review tools that invoke claude -p as a reviewer subprocess
  • Multi-agent orchestration where a parent claude session uses the Bash tool to run claude -p for subtasks
  • Any CLI tool that shells out to claude -p and is itself invoked from the Bash tool

The data is actually produced (provable via file redirects), so this is purely an output capture/reporting bug in the Bash tool, not a data loss issue.

Environment

  • Claude Code version: 2.1.55
  • OS: macOS 15.7.4 (Darwin 24.6.0 arm64)
  • Shell: zsh
  • Bun: 1.3.6
  • Node: v25.2.1

View original on GitHub ↗

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