[BUG] Pipes silently broken in sandbox: shell-quoted "<" in oAD passes literal argument to eval instead of redirect

Resolved 💬 3 comments Opened Mar 7, 2026 by Aquaticat Closed Apr 16, 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?

All pipes in the bash sandbox produce no output. echo hello | cat returns nothing. echo hello | wc -l returns 0.

The function oAD constructs the /dev/null stdin redirect by calling shellQuote([command, "<", "/dev/null"]), which produces 'echo hello | cat' '<' '/dev/null'. The shell-quoted '<' is a literal string argument, not a redirect operator. When eval receives these three arguments, it joins them into echo hello | cat < /dev/null, redirecting the rightmost pipeline component's stdin from /dev/null and overwriting the pipe fd.

A correct pipe-aware path (HLD) exists but is gated on !useSandbox, so it never runs inside the sandbox.

What Should Happen?

echo hello | cat in the sandbox should output hello. The < /dev/null should redirect eval's stdin (preventing reads from the IPC socket), not become part of the eval'd command string.

Error Messages/Logs

# bash -x trace of the broken behavior:
+ eval 'echo hello | cat' '<' '/dev/null'
++ echo hello
++ cat
# no output — cat reads EOF from /dev/null

# bash -x trace of correct behavior (unquoted <):
+ eval 'echo hello | cat'
++ echo hello
++ cat
hello


strace of `cat` child process in broken case:


dup2(3, 0) = 0         # do_piping: fd 0 = pipe read end
close(3) = 0
openat(AT_FDCWD, "/dev/null", O_RDONLY) = 3
dup2(3, 0) = 0         # overwrites pipe with /dev/null
close(3) = 0
execve("/usr/bin/cat", ["cat"], ...)

Steps to Reproduce

The bug affects every pipe command in the sandbox. No special setup needed:

echo hello | cat          # no output
echo hello | wc -l        # 0
ls | head                 # no output

Workarounds that produce correct output:

echo hello | cat; true    # "hello" — < /dev/null redirects `true` instead of `cat`
bash -c 'echo hello | cat'  # "hello" — subshell doesn't inherit the redirect

Disabling the sandbox also fixes it (the HLD path runs instead of oAD).

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.71

Platform

Anthropic API

Operating System

Other Linux

Terminal/Shell

Other

Additional Information

Terminal: Ptyxis

Claude's writeup is attached.

PIPE-BUG.md

View original on GitHub ↗

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