Bash/Read tool results intermittently return empty (then flush late, redundantly) on Linux — NOT length/concurrency-correlated; same symptom as stale-closed #36038
Summary
In a long, highly-concurrent session, Bash and Read tool calls intermittently return empty content to the model even though the command succeeded (exit 0) and the file/stdout is correct (side effects like file writes happen). This is the same symptom as #36038 ("Bash tool output silently empty … in long sessions"), which was reported on Windows/Git Bash and stale-closed (not_planned) without a fix — but it reproduces here on Linux, so the underlying cause does not appear to be Windows-specific.
A distinctive extra detail: the missing outputs are not dropped — they flush late, arriving as a batch in a later turn, after the calls had already been retried successfully.
Environment
- Claude Code 2.1.156 (native installer,
claude-native-aarch64). Latest at time of report: 2.1.157; stable tag: 2.1.148. - Platform: Linux (kernel 6.8.x), shell: zsh.
- Usage pattern: long session with heavy concurrency — many background subagents /
Workflowruns and parallelBashbatches.
Steps / observations
- Run a
Bashcommand that reads or writes a file (cat,wc -l,git log,od -c, etc.). The tool result comes back blank. - The data was never missing:
od -c <file>(or a re-read) in a following call shows the full bytes; the command had completed and its side effects (file writes) were present. - The backed-up outputs later arrive as a batch of ~10–15 previously-blank results at once in a single assistant turn — typically one to a few tool-call rounds later, and after I had already re-run those calls and received successful results. So it is redundant / duplicate late delivery (the originals eventually flush on top of the successful retries), not merely slow original delivery.
- Onset and persistence match a buffer filling up: it starts after the session has run long / pushed a lot of output, and once it starts, blanks recur in clusters.
- Affected both the main loop and background subagents, intermittently (the same session also had subagent calls that returned output fine — e.g. a freshly-spawned verification subagent worked).
Edit/Writesuccess confirmations still arrived during stretches whereBash/Readresult bodies were blank.
Expected
Each tool result is delivered to the model in the turn the tool completes.
Actual
The result body is intermittently empty for that turn; the content arrives batched in a later turn, redundantly, after retries have already returned.
Relationship to existing issues
- #36038 ("Bash tool output silently empty on Windows (Git Bash) in long sessions"; CLOSED
not_planned— auto-closed as stale for inactivity; no maintainer response, no fix): the closest prior art and almost certainly the same bug. Its body describes this symptom near-verbatim — empty output even forecho, worsening as the session gets longer, "once it starts, ALL subsequent Bash calls return empty," commands still execute (file writes happen) but stdout/stderr isn't captured, delegating to an Agent/subagent works fine, and restarting fixes it temporarily. A commenter hypothesized pipe-buffer exhaustion (the pipe fills over a long session, after which reads return empty). It was reported on Windows 11/Git Bash and carriesplatform:windows, but nothing in it establishes the cause as Windows-specific — and this report shows the same behavior on Linux at 2.1.156. Likely a never-fixed, cross-platform buffering bug that was simply stale-closed; worth reopening or superseding. - #54847 (tool dispatch stalls silently, 2.1.121–2.1.123, no disk side-effects): different — here commands do have side effects, and the version is past that regression window.
- #53862 (interactive Bash hangs after success;
tool_resultnot written): related, but taggedplatform:macos/area:providersand described as a hang, whereas this is a later redundant flush on Linux with no proxy. - #39830 (parallel Agent calls lose
tool_result; closed): surfaced as a[Tool result missing]placeholder; here results are blank then flushed late, no placeholder.
Hypothesis
A result-delivery buffering / back-pressure problem rather than a dispatch failure: commands run and their side effects land, but stdout/stderr isn't captured for that turn. This matches #36038's pipe-buffer-exhaustion hypothesis (a long, high-throughput session fills a buffer; once full, reads come back empty), and is consistent with what's seen here: onset after a long, concurrency-heavy session (many parallel Bash batches + background subagents), then a late batched flush once the buffer drains. The separate "Bash output lost when running multiple Claude Code sessions in the same project directory" changelog fix feels adjacent.
Two wrinkles worth noting:
- The late flush is redundant with successful retries (duplicate late delivery), which argues against "just latency."
- At least once a result came back not merely empty but containing fabricated text that was never in the underlying file (caught by re-reading the file a different way) — so the failure mode isn't always a clean blank.
Impact
In a long multi-agent session this is corrosive: a blank result is easily misread as "the command failed / the file is empty / something is broken," prompting a wrong (sometimes destructive) corrective action when the operation actually succeeded.
Workarounds observed (from #36038, and consistent here)
run_in_background + reading the output file; delegating to a fresh subagent; periodic /compact; restarting the session.
12 Comments
been seeing weirdness like this spuriously past few hours even on a fresh session. not sure if same issue as this thread or #63792 or maybe they're all linked, but I've tried disbling dynamic tool loading as per that other issue to see if that resolves it. will report back if I see any more of it with this setting. the harness issues also caused it to accidentally spawn 2 sub agents for the same task in that session
(this is on WSL btw)
<img width="731" height="579" alt="Image" src="https://github.com/user-attachments/assets/9296ff1f-215d-4777-b2fb-663fbba8c8a6" />
Correction: this is NOT correlated with session length or concurrency
Updating with a repro that contradicts the central hypothesis in the original report.
The original framing (and title) blamed long, highly-concurrent sessions and a pipe-buffer / back-pressure mechanism: blanks start "after the session has run long / pushed a lot of output," buffer fills, etc. I no longer think that's right.
Since filing this I:
The blanking then reproduced in a session that was:
It still presented the same way: several
Bash/Readresults came back blank despite exit 0 and correct side effects, then flushed late and redundantly a few tool-rounds later, on top of successful retries — and the misread-as-failure hazard is the same (it briefly led me to believe a set of files was missing when they were intact).So:
Net: the symptom is real and reproducible, but the conditions are broader / different than reported — root cause unknown, but it is not gated on session length or concurrency. Suggest revising the title to drop "in long, highly-concurrent sessions."
Environment for this repro: Linux (kernel 6.8.x), zsh, Claude Code 2.1.157 (native installer), single session, post-restart.
update: still happening with dynamic tool loading disabled
<img width="973" height="919" alt="Image" src="https://github.com/user-attachments/assets/4105abb2-0e3d-42eb-add5-359f15e32583" />
This is happening for me as well, on Mac. It seems to have just started happening within the past day.
occasionally i also get these type of spurious failures . am on v2.1.157 for reference
It is happening for me on mac too, also within the past day.
Same signature as here:
Bash/Read/ MCP /ToolSearchoften return empty in the live UI even though the command ran (files land on disk with the right byte counts). Held results then flush late and out of order — sometimes a whole batch of earlier “empties” arrives after a laterechoprobe or unrelated tool call.I reproduced while researching this and filed a fuller report with JSONL forensics: #63966
Redacted subagent transcript: https://gist.github.com/genesiscz/e26824e05751c1623d3442fee5ea0eb7
Quick numbers from background subagent on CC 2.1.158 (session
ab652a80, 2026-05-30):tool_use↔tool_resultin JSONL — 0 orphans (commands ran; delivery lag, not missing execution)Readof/tmp/gh-research-1.txt: 15 other tool uses betweentool_useandtool_result(~18s), then 3487 B appearedReads of/tmp/gh-detail-1.txtlooked empty live; JSONL later has ~18 KB bodies;wc -con disk matched the writingBashcallserver_tool_useadvisor: 1 invocation, notool_resultin the transcript (actual drop)Environment: macOS 26.x (darwin 25.3.0), zsh,
claude-opus-4-8,ENABLE_TOOL_SEARCH=true, experimental agent teams,CLAUDE_CODE_NO_FLICKER=1./private/tmp/claude-__UID__/only 32K here — doesn’t look like #51814 tmpfs full. PreToolUse hooks unchanged and worked before (not blaming hook script content; possible harness regression under parallel load).Workaround that helped: redirect output to
/tmp,Readit, retry until flush; smallechoprobes to unstick the queue.Agree with @cwalv that this may not be gated on “long session only” — mine hit during a heavy parallel
ghresearch batch in a fresh subagent, same day as #63859 on 2.1.158.it's happening more past couple days. I wonder if it's even the harness or if it's something on the backend side
<img width="639" height="626" alt="Image" src="https://github.com/user-attachments/assets/5454f5bf-7a43-4a85-8818-6a44967415a8" />
Here's a screenshot of the problem in action. Note the bash command is still marked as running in my screenshot, even though control has been returned to the agent (and it's subsequently issued all the
printf draincommands to try to figure out why it's not getting the results back from the tool run). Also note theReading 1 file... (ctrl+o to expand)says "Reading", not "Read", and the dot to the left of that line is doing the pulsating animation that means the tool call is still in progress:<img width="1364" height="966" alt="Image" src="https://github.com/user-attachments/assets/ae33cf07-6779-4b41-9b88-e026268575fb" />
Reproduced on Linux with Opus 4.8 in a long Claude Code session today (CLI 2.1.158).
Exact manifestation matching this report:
results then flushed late, duplicated, and out of order on a subsequent turn (same single
output appeared 4-5x attributed to different calls).
Cancelled: parallel tool call ... erroredeven though they had no dependency on the failed one(cf. #63576 / #64246).
on a false premise before the real output arrived.
Confirming the workaround: running tools one-at-a-time (single tool call per turn) fully avoids
it; ~~
DISABLE_PARALLEL_TOOL_USE=1is the practical switch.~~ [← incorrect, see edit note above] Sequential calls were 100% reliable inthe same session where parallel batches failed ~1 in 6-8 times. Adding a Linux + Opus 4.8 data point
to CC-4471.
@nerdpudding Where did you get
DISABLE_PARALLEL_TOOL_USE=1? As far as I can tell, no such environment variable is supported by Claude Code. The documentation section on environment variables does not list it.There is an API tool flag named
disable_parallel_tool_use, although it's a boolean and it's only for the API (documented here) – it's not for use in Claude Code:The only environment variable that seems like it _might_ achieve this is
CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY. It defaults to10, so setting it to1_might_ be a suitable workaround. It really depends on where the bug is:[tool1, tool2, … toolN], then it will run them one after the other, and finally it will send the batch of[tool_response1, tool_response2, … tool_responseN].If the issue is will the way the harness prepares this batch of responses, then it might not help at all. In fact, look at the screenshots shared here and in related threads: the model often tries to run a single tool call like
echo helloand even _that_ fails. So how is that related to concurrency?Correction to my earlier comment — the env var I cited does not exist.
@nicolasff is right, thanks for catching it. I checked the installed Claude Code binary (v2.1.159) directly:
DISABLE_PARALLEL_TOOL_USE— 0 occurrences (not a CLI env var at all)disable_parallel_tool_use— 1 occurrence, the API-side tool flag you pointed to, not a Claude Code settingCLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY— present (the real concurrency knob)So my earlier "suggested workaround" line was simply wrong about that variable.
Full disclosure on how that happened, because it's relevant: I had Claude Code itself research this thread and draft my previous comment on my behalf. I only told it, naively, "add to the existing issue that I'm affected too," and I did not verify the env-var claim before it went out. That's on me — it's exactly the kind of plausible-but-wrong detail that shouldn't end up in a bug thread. Apologies for the noise.
To be clear, I am not now putting forward
CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY=1as a confirmed fix either. I haven't verified that it helps, and as @nicolasff notes, if even single tool calls fail then forcing concurrency to 1 may not address the root cause anyway.Honest status of the only "workaround" I have: nothing at the config level that I've confirmed. The closest thing is prompting the model, inside a session, to deliberately issue one tool call per turn. It only helps a little — the model is aware of the instruction and tries to avoid parallel calls for a while, but after a bit it tends to drift back into batching them and the failures return. So it's not even a reliable workaround, let alone a solution; the underlying empty / late / duplicated tool-result delivery is still there.
Closing for now — inactive for too long. Please open a new issue if this is still relevant.