Your subagent failed. Now what?
It is a fair question, and it does not have a comfortable answer, because a subagent is the one part of Claude Code you cannot step inside. A failed function call leaves a stack trace. A failed subagent leaves a sentence. It did its work behind a closed door, and all you got back was a note slid underneath it.
That is not a flaw to fix. It is the design, and the design is the reason subagents are useful. A subagent runs in its own context window precisely so its forty file reads and its noisy tool output never reach yours. The isolation that keeps your main session clean is the same isolation that keeps you from watching the subagent work. You cannot have one without the other.
So debugging a subagent is a different skill from debugging code. It is not about reading a trace. It is about reading a summary, recognizing the small set of ways isolation goes wrong, and, more than anything, designing subagents that report enough about themselves to be diagnosed at all. This post is that skill.
Why subagents fail in the dark
To debug a subagent you have to know what it can and cannot see, because almost every subagent failure traces back to that boundary. The subagents documentation is precise about it: each subagent “starts with a fresh, isolated context window. It does not see your conversation history, the skills you’ve already invoked, or the files Claude has already read.” Claude writes it a delegation message describing the task, and the subagent works from that message and whatever it can discover with its own tools. Nothing else.
Hold that picture, because it explains the opacity in full. The subagent cannot see your session, and your session cannot see the subagent. What crosses the boundary is two things and only two things: a delegation message going in, and a summary coming out. Everything in between, the files it chose to read, the searches it ran, the dead ends it backed out of, the reasoning it used, happens in a context window that is discarded when the subagent finishes. There is no log to open afterward because the working context no longer exists. This is why a subagent failure feels so much worse than a normal bug. It is not that the information is hard to find. It is that most of it was never kept. Debugging in the dark means accepting that you are working from two artifacts, the brief you sent and the summary you got, and getting as much out of those two as they can give.
Start with the summary
The summary is the only direct evidence you have, so read it like evidence, not like a status update. Most people skim it, see the word “done” or “failed,” and move on. The summary almost always says more than that if you slow down.
Ask three things of it. Did the subagent understand the task the way you meant it? A summary that describes solving a slightly different problem tells you the delegation message was ambiguous, and that is a fixable thing. Did it report what it could not do, as opposed to what it did? Phrases like “I was unable to locate” or “no matching files were found” are the subagent telling you it hit the edge of what it could see. And did it hand back a result or a description of a result? A subagent that says it “would” do something, or describes the change it “recommends,” often did not actually do it, and that gap is the bug. The summary is a small artifact, but it is a dense one. The failure is usually named in it, in plain language, and the only reason people miss it is that they expected a stack trace and got a paragraph instead. Read the paragraph.
The context-isolation failure
When the summary does not explain the failure on its own, the cause is almost always the same one, and naming it makes it easy to spot. The subagent could not see something it needed, because it started fresh.
This is the failure mode that catches everyone, because it is invisible from your seat. You can see the whole conversation, so the task feels fully specified. But the subagent only received the delegation message. If the task depended on something established earlier in your session, a decision you made, a file Claude already read, a convention you stated, the subagent never received it. It did not fail because it is weak. It failed because it was briefed badly, and it was briefed badly because the brief was written by a Claude that forgot the subagent cannot see what it can see.
There is a related version worth knowing. A subagent inherits the parent’s permissions with tool restrictions on top, so a subagent scoped to read-only tools that is then asked to make a change cannot do it. The summary will usually say so, but if you skimmed it you will read the refusal as a model failure rather than a permissions one. If you keep hitting these and want a second pair of eyes on how your team scopes and briefs its agents, my door is open. The fix for the whole category is the same: the subagent is only as good as its delegation message, so when one fails for no visible reason, suspect the brief before you suspect the subagent. The deeper background on this boundary is in what a subagent is, and it is worth being fluent in it.
Design subagents to be read
Reactive debugging only goes so far when the evidence is this thin. The real move is to stop relying on whatever summary you happen to get, and design subagents that report on themselves by default. A subagent you wrote for observability is one you can debug. A subagent you wrote and forgot is one you can only guess at.
Two habits do most of the work. First, give a custom subagent an explicit return contract. In its system prompt, state exactly what its summary must contain: what it did, what it could not do and why, which files it changed, and what it would need to finish if it ran out of room. A subagent told to report its own boundaries will report them, and a vague failure becomes a specific one. Second, brief it as though it knows nothing, because it does. Put every fact the task depends on into the delegation message itself rather than trusting that context will carry over, since it will not. Most of what looks like a flaky subagent is really an under-specified one, and both fixes are about writing, not debugging. You are not fixing the subagent after it fails. You are building one that, when it fails, tells you why.
When to stop and go inline
The last skill is knowing when to stop. Subagent debugging has a point of diminishing returns that arrives faster than with ordinary code, because every diagnostic cycle is expensive: you adjust the brief, you spend a whole fresh context window running the subagent again, you read another summary. Two or three rounds of that and you have spent more than the isolation was ever going to save.
When you reach that point, the answer is to pull the work back into your main session and do it inline, where you can see every step as it happens. You lose the clean context, which is a real cost. You gain full visibility, which is exactly what you were missing. For a task that is being stubborn, that trade is correct. The same is true if the work turns out to need broad context to begin with: that is the case for the general-purpose agent, which spawns as a fork and inherits your conversation, or for not delegating at all. A subagent is a worker sent into another room. Most of the time that is the right call, and the closed door is a feature. But when the door has stayed closed through three failed attempts, stop knocking. Open it, bring the work into the room you are standing in, and watch it run.



