[BUG] Bash tool silently truncates commands over ~8 KB and reports it as a quoting error

Status Open
Reported on v2.1.226
Maintainer reply None cached
Activity 1 comment · opened Aug 8, 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?

The Bash tool silently truncates commands above a size threshold, and the resulting failure is reported as a bash quoting error that points at innocent content. Nothing in the command runs.

The novel part is that this is size-dependent and deterministic. There are several open issues reporting this same error string on Windows (#83243, #82376, #81732, #71591, and the auto-closed #68337), but all describe it as happening on trivial commands or as a session that breaks permanently. None identify command length as the variable. Below the threshold everything works perfectly, including heredocs full of apostrophes and backticks; above it, everything fails.

Measurements. Each probe self-reports the length it received on success, so passing sizes are exact. Failing sizes are approximate, because a truncated command produces no output.

| Tool | Command bytes | Result |
|---|---|---|
| Bash | 7,238 | pass |
| Bash | ~8,300 | fail |
| Bash | ~8,400 | fail |
| Bash | 9,431 | fail (original real-world case) |
| Bash | 10,875 | fail (contained no quote characters at all) |
| PowerShell tool | 9,045 | pass |
| Write tool (content param) | 9,293 | pass |

It is not the transport. The PowerShell tool carried 9,045 bytes and the Write tool a 9,293-byte parameter in the same session, well past where Bash fails. The limit is specific to the Bash tool.

Why the error misleads. The wrapper appears to be <inlined shell snapshot> && ... && eval '<user command>'. Truncation cuts inside that quoting, leaving the wrapper's own ' unclosed, so bash blames whichever quote ends up unmatched:

  • With no apostrophes in the command, it blames the wrapper's quote at line 1.
  • With prose in the command, it blames an ordinary apostrophe in that prose. In my original case it cited line 76 of 95, which is neither the truncation point nor a defect.

Individually tested and ruled out as causes, all fine below the threshold: apostrophes, backticks, fenced code blocks, && before a heredoc, markdown headings, markdown blockquotes, heredocs generally.

A hypothesis that may connect this to the other open reports

The wrapper fragment leaked in #82376 shows shell-snapshot content (builtin unalias, builtin unset -f) inlined directly into the bash -c string, followed by eval '<user command>'. My snapshot is 2,952 bytes / 44 lines, most of it one very long exported PATH.

If the inlined snapshot consumes the same byte budget as the user command, then the effective limit is not fixed. It shrinks as the snapshot grows, and the snapshot grows with PATH length and accumulated shell state. That would predict exactly what the other issues report:

  • #83243, #82376: eventually every command fails, including echo hi, once the prefix alone approaches the budget.
  • #82376 specifically: a heredoc with contraction-heavy prose failed first, before trivial commands did. Escaping apostrophes inflates the string, so that call would cross the threshold earliest.
  • #82376: a new session fixes it while restarting the app or the machine does not, which fits a fresh, smaller snapshot rather than corrupted state.
  • The varying line numbers across reports (86, 87, 117, 120, 123) look like positions inside inlined wrappers of differing sizes, not anything in the user's command.
  • #81732 audited 322 snapshot files, found them all syntactically valid, and concluded the fault is in "the unseen command string assembled around snapshot sourcing." A size limit on that assembled string is consistent with that conclusion.

I want to be clear this is a hypothesis. What I have measured directly is the threshold and the tool-specificity; the connection to the other issues is inference from #82376's leaked fragment.

What Should Happen?

  1. Reject rather than truncate. Return the byte count and the limit. Claude Code already does exactly this elsewhere: the PowerShell permission pre-parser returns PowerShell parser: command too long (${bytes} bytes, max ${max}). Applying that existing pattern to the Bash path would turn a multi-session mystery into one line of output.
  2. Do not let the wrapper prefix silently consume the user's budget. If the snapshot is inlined, either source it by path or subtract its size when validating.
  3. Document the limit in the Bash tool description, which currently documents the 30,000-character cap on output and says nothing about a cap on input.

Error Messages/Logs

Exit code 2
/usr/bin/bash: -c: line 1: unexpected EOF while looking for matching `''

The command that produced this contained no ' character anywhere.

Steps to Reproduce

  1. On Windows with Git Bash, run any Bash tool command whose text is comfortably under 7 KB. It succeeds.
  2. Run a Bash tool command of roughly 8.5 KB. Content is irrelevant; the minimal case has no quote characters at all:
X=<about 8300 digits>; echo len=${#X}
  1. Observe exit code 2 and unexpected EOF while looking for matching ''`, with no indication that length was involved and no side effects.
  2. For contrast, send the same payload size through the PowerShell tool or the Write tool. Both succeed.

To self-measure the boundary, X=<digits>; echo len=${#X} reports the exact byte count on any run that survives.

Claude Model

Opus

Is this a regression?

I don't know

Claude Code Version

2.1.226 (Claude Code)

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Git Bash (Git for Windows) via the Bash tool; PowerShell 7 is the environment's primary shell

Additional Information

Related open issues reporting the same error string on Windows, which this may underlie: #83243, #82376, #81732, #71591, #73701, and the auto-closed #68337.

The practical workaround, once the cause is known, is to stop putting content in the shell: write files with the Write tool and pass the path (gh ... --body-file, git commit -F). That is better practice anyway, which is part of why this stays undiagnosed. Each encounter looks like your own quoting mistake, so you fix it by other means and never file it.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗