[BUG] Bash tool hangs indefinitely when 2>&1 combined with pipe — regression in 2.1.x, high frequency with non-Anthropic backends

Resolved 💬 3 comments Opened May 23, 2026 by TPdog Closed Jun 23, 2026

Describe the bug

Bash tool commands that combine 2>&1 (stderr→stdout redirect) with a pipe (|) cause the CLI to hang indefinitely — no output, no timeout, no recovery. Requires killing the Claude Code process.

This is a regression in 2.1.x. Did not occur on older versions.

Related closed issues (same root cause, never fixed)

  • #19060 — "CLI freezes with No messages returned" — same 2>&1 | tee trigger, closed as "not planned" without fix
  • #5264 — "Bash tool treats 2>&1 as literal arguments" — closed as duplicate, root cause never addressed

Environment

  • Claude Code version: 2.1.150
  • Model backend: DeepSeek V4 Pro (via ANTHROPIC_BASE_URL)
  • OS: Windows 11 Home (10.0.26100)
  • Shell: bash (Git Bash / MSYS2)

Steps to reproduce

  1. Make any Bash tool call that uses 2>&1 combined with |
  2. Wait — the command hangs indefinitely

Examples that trigger the hang:

mvn compile 2>&1 | grep ERROR
npm run build 2>&1 | tail -20
find . -name "*.java" 2>&1 | wc -l

Frequency

~3 times per 10 minutes during normal development workflow.

Expected behavior

Command executes and returns output normally, like in any standard shell.

Workaround (confirmed)

Three alternatives work:

  1. Drop 2>&1 (preferred) — Bash tool already captures and merges both stdout and stderr:

``bash
mvn compile | grep ERROR
``

  1. Wrap in bash -c:

``bash
bash -c 'mvn compile 2>&1 | grep ERROR'
``

  1. Two-step with file:

``bash
mvn compile > /tmp/build.log 2>&1
grep ERROR /tmp/build.log
``

Root cause speculation

The Bash tool's command parser was significantly refactored in the 2.1.145–2.1.149 range. The bash -c workaround working while the bare command hangs confirms the parser is mishandling shell metacharacters — likely tokenizing 2>&1 as literal positional arguments instead of a shell redirect operator, which then interacts poorly with the pipe splitting logic.

With non-Anthropic backends (DeepSeek, OpenRouter, etc.), the frequency is much higher — possibly because the stream/timing characteristics differ, exposing race conditions in the output capture mechanism.

View original on GitHub ↗

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