[BUG] Subagent Write tool rejects .md files named "report"/"summary"/"findings"/"analysis" — no opt-out

Status Open
Reported on v2.1.92
Maintainer reply None cached
Activity 8 comments · opened Apr 7, 2026

What's Wrong?

Subagents spawned via the Agent tool are blocked from writing .md files when the filename starts with report, summary, findings, or analysis (case-insensitive). The Write tool returns an error:

Subagents should return findings as text, not write report files. Include this content in your final response instead.

This restriction was recently activated server-side — it was not present in earlier sessions on the same version (2.1.92). It breaks established workflows where subagents are explicitly instructed to write results to files.

There is no way to opt out: no setting in settings.json, no environment variable, no CLAUDE.md directive.

What Should Happen?

When a user explicitly instructs a subagent to write results to a file, the Write tool should respect that instruction. At minimum, there should be a way to opt out of this restriction.

Error Messages/Logs

Subagents should return findings as text, not write report files. Include this content in your final response instead.

Steps to Reproduce

  1. Spawn a subagent via the Agent tool with a prompt that explicitly instructs it to write results to a file:

"Write your findings to /tmp/test/report.md"

  1. The subagent attempts to use the Write tool to create report.md
  2. Write fails with the error above
  3. The subagent falls back to including the full content in its response, consuming the parent's context

Note: This is controlled by a server-side feature flag being rolled out gradually. It may not reproduce for all users yet.

Model: Opus

Regression?: Yes, this worked in a previous version

Last Working Version: Same version (2.1.92). Worked on Saturday April 5, stopped working Monday April 7. The restriction is server-side, not version-dependent.

Claude Code Version: 2.1.92

Platform: Anthropic API

OS: Ubuntu/Debian Linux

Terminal: iTerm2

Additional Information

Why subagent file writes matter: Some users design their subagent workflows to write results to files rather than returning them in the response. This is intentional, not accidental:

  1. Persistence — Subagent results survive context compaction. Response-only results are lost when the conversation is compressed.
  2. Context efficiency — The parent reads the file when needed, rather than having the full content injected into its context by the response.
  3. Fidelity — Direct file writes avoid information distortion from the parent re-serializing the subagent's output.

The current restriction assumes all subagent file writes are unintentional, and blocks them with no recourse. Users who have deliberately optimized their workflows around this pattern are affected.

Suggested fix: Add a setting (e.g., in settings.json) to disable this restriction. Users who want the guardrail keep it by default; users who don't can opt out.

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)

View original on GitHub ↗

8 Comments

kjerk · 4 months ago

Context: Win10, Windows Terminal, PWSH-7.5.4

The current restriction assumes all subagent file writes are unintentional, and blocks them with no recourse. Users who have deliberately optimized their workflows around this pattern are affected.

This is the big one, just ran into this issue myself and came looking for a mitigation. This is a huge regression if you've written skills or workflows that have agents that are meant to write a report on purpose, instigated by the controlling main prompt with an expected landing zone. Everything there is exactly as expected, this is simply a harness error at that point. If accept-edits is on, or the write permission is autoflagged as good, I'm not sure what the problem is here. In my instance of CC, the sub agents were actually locked and not responsive and I had to kill them, go posthumously look at their .jsonl files, and the last entries were like

{
	"parentUuid": "...",
	"isSidechain": true,
	"promptId": "...",
	"agentId": "...",
	"type": "user",
	"message": {
		"role": "user",
		"content": [{
			"type": "tool_result",
			"content": "<tool_use_error>Subagents should return findings as text, not write report files. Include this content in your final response instead.</tool_use_error>",
			"is_error": true,
			"tool_use_id": "toolu_014dYLcC9MLFKdheSB3RkkRi"
		}]
	},
	"uuid": "...",
	"timestamp": "2026-04-16T00:56:03.210Z",
	"toolUseResult": "Error: Subagents should return findings as text, not write report files. Include this content in your final response instead.",
	"sourceToolAssistantUUID": "...",
	"userType": "external",
	"entrypoint": "cli",
	"cwd": "C:\\Path\\to\\Project",
	"sessionId": "...",
	"version": "2.1.110",
	"gitBranch": "main",
	"slug": "magical-searching-wadler"
}

With no further action.

Occurring only after they wound up locked, at which point I had to go rescue their attempted writes by exfiltrating them from the .jsonl files where the (already written) reports had gotten lodged on the write attempt, wasted. Had they continued and listened the the tool error instruction, it would have just returned the entire giant report to the main context and blown that up instead.

0xbrainkid · 4 months ago

A server-side restriction that blocks subagent Write calls for filenames matching "report/summary/findings/analysis" with no opt-out path is a significant workflow-breaking change — especially for established agent pipelines where subagents are explicitly instructed to write results to files.

From an agent identity and capability perspective, this introduces a covert capability restriction: the Write tool is declared as available to subagents, but the server is silently blocking a subset of calls based on filename. The subagent believes it has Write capability, attempts to use it, and fails — without any indication in the tool definition or settings that this restriction exists.

Two core problems:

1. No opt-out is the main issue. Users who explicitly instruct subagents to write to report files have a legitimate use case. A security guard that cannot be disabled forces all users — including those with legitimate workflows — to work around it. The fix could be as simple as a settings.json key: "allowSubagentReportFiles": true.

2. The fallback degrades the multi-agent pipeline. When the Write tool is blocked, the subagent falls back to including results in its response text. This consumes parent context budget for content that was specifically meant to be persisted to a file. In a multi-step agent pipeline, this can cause cascading context exhaustion.

The right model: server-side safety restrictions should be opt-out-able by users who explicitly configure them, and should be surfaced in the tool definition (so agents know the restriction exists before attempting the blocked call) rather than returned as a runtime error after the call is made.

rudra-sett · 4 months ago

Also seeing this and agree with the above - part of my workflow explicitly requires subagents to write to ~/working/notes/report*.md, this is no longer working for the same reason!

thomastay · 4 months ago

seeing the same issue. I'm using a Haiku agent to write a report since it just needs to read a JSON output and write a report, something really quick for Haiku. I'm doing this to reduce the Opus costs and this restriction is really disappointing.

techjoec · 3 months ago

tengu_subagent_md_report_blocked

that's the flag they intentionally added against this. I used this heavily too and it was a huge context saver for the current session!

If you grep the claude binary you will find that flag plus: 
if(q.agentId&&/^(REPORT|SUMMARY|FINDINGS|ANALYSIS).*\.md$/i.test(rcH.basename(K)))return d("tengu_subagent_md_report_blocked",{contentBytes:Buffer.byteLength($)}),{result:!1,message:"Subagents should return findings as text, not write report files. Include this content in your final response instead.",errorCode:5};let A=y58(K,$);if(A)return{result:!1,message:A,erro

@ant* folk, uhhh what's up? Why is this something we are not allowed to do? Really curious on this because we'll just waltz the regex anyway.....Is it causing a problem? Is there something better we can do? Too often I get a firehose of subagent context slamming my session and degrading the quality. I used it and trained some logics into memory and such that my session knows to "sip" the outputs via this, and then I have them available for deeper dives later! Hmm

quantuan125 · 2 months ago

Any update on this?

tmountjr · 2 months ago

I just recently got bit by this - I had been using Claude as a research engine and maintaining an evergreen summary.md file with my findings updated as a result of successive research runs. At some point one of the three output files (summary.md) stopped being written. Looks like it's a server-side flag for subagents affecting specific .md filenames. In my case I could rename my summary file to something that doesn't match /^(REPORT|SUMMARY|FINDINGS|ANALYSIS).*\.md$/i and then refactor the entire project to catch the name change; but instead I came up with a recovery hook that triggers on SubagentStop and recovers any blocked files by reading the transcript of the subagent, finds files that were blocked, and uses the main agent to write that content verbatim to disk. So far that actually seems to work well, and it let me avoid refactoring my entire skill and agent definition to avoid an undocumented feature flag that could change at any time. It's also nice because the main agent doesn't have to really _do_ anything other than find the blocked text and dump it out.

(Honestly that's the most annoying part of this - at some point they could decide to block .txt files too or add another name to the list of blocked files and if I chose, say, overview.md today and tomorrow they blocked overview in the regex too, I'd have to wait for it to fail, then choose another name and do another round of refactoring.)

jesse-lapin · 1 month ago

Adding a data point on mitigation, since a few people above are looking for one, plus a
consequence of @techjoec's regex find that may help anyone who can rename.

Preventive mitigation that has held for us: put the fallback in the spawn prompt.

Rather than recovering blocked writes after the fact, every subagent prompt in our
orchestration framework carries one paragraph:

If a Write call is refused with "Subagents should return findings as text, not write report files", do NOT return the content as text — write the identical content via cat > FILE <<'EOF' … EOF and verify with ls.

Across roughly 20 subagent spawns in one unattended run (planner/executor/verifier agents
whose entire contract is producing artifacts on disk), that held with zero lost
artifacts
. The important part is that the agent has to be told, because the error text
instructs it to do the one thing that loses the artifact — return findings as text. An agent
that hasn't been told complies with the error, the parent then looks for the file, and
depending on the parent's rigor the run either stalls or proceeds with a silently missing
artifact.

The regex is anchored, so a prefix defeats it. From @techjoec's extraction —
/^(REPORT|SUMMARY|FINDINGS|ANALYSIS).*\.md$/i — the match is on the start of the
basename. So SUMMARY.md is blocked while 01-SUMMARY.md, phase-2-summary.md, etc. are
not. Worth knowing before refactoring a whole project around a rename: a numeric or phase
prefix is usually enough, and it's less invasive than changing the noun.

One more argument for an opt-out, in addition to the ones above: the working fallback
moves artifact writes out of a structured tool call and into shell heredoc interpolation.
That is strictly worse for quoting correctness (content containing the delimiter, or
$/backticks in an unquoted heredoc) and worse for auditability, since the write no longer
appears as a Write tool call in the transcript. The guard's practical effect is to push a
class of writes onto a less safe path rather than to prevent them — probably not the intent.

A stable error identifier would also help: there's an errorCode: 5 in the extracted
snippet, but since neither the code nor the message is documented, a fallback can only
key on prose that may be reworded.