This was the problem that bothered me most. You'd ask Iris to delegate a question to a specialist. The specialist would fail - maybe the AI provider returned a 503 (server overloaded), the model timed out, or the rate limit was hit. The parent agent would tell you: "I wasn't able to connect to the specialist." And that was it. Your question went unanswered.
The restaurant analogy
You call a restaurant. The host says "the chef isn't in today" and hangs up. The host could make you a sandwich. They could check if another chef is available. They could at least offer an alternative. Instead, they just gave up on your behalf.
That's what the orchestration system was doing. The parent agent is a capable AI model. It has the full context of your question. It knows what was asked. It received the specialist's failure status. And it chose to report the failure rather than do the work itself. In engineering we'd call this failing to degrade gracefully - when part of the system breaks, the whole thing should get a bit worse, not completely stop working.
The takeover pattern
In backend engineering there's a well-known pattern called a circuit breaker with fallback. Think of it like an electrical fuse: when the main circuit (the specialist) fails, instead of the whole house going dark, the system automatically switches to a backup generator (the parent agent). The backup might not be as specialised, but it keeps the lights on.
When a sub-agent fails now, the tool result includes two things: the failure status with the reason, and something I'm calling a takeover directive - the original prompt that was meant for the specialist, packaged with an instruction telling the parent to answer it directly. Don't apologise about the specialist. Don't suggest trying later. Just handle it, briefly noting you're stepping in.
The directive uses the same inline instruction injection technique from the re-summarisation fix (embedding behaviour instructions right next to the relevant data in the tool result). This puts both the context ("here's what was asked") and the instruction ("answer it yourself") right in the model's attention window, where it's hardest to ignore.
This works across three scenarios, each a different level of graceful degradation:
All specialists fail. Say you dispatched two agents and both returned errors. The parent receives a directive listing both original prompts with their failure reasons. It answers both questions itself. The entire specialist layer is bypassed - total fallback, but the user still gets answers.
Some specialists fail. One agent succeeds, one fails. The parent presents the successful result normally and takes over only the failed prompt. You can see which specialist delivered and which one the parent handled directly. The system delivers what it can through the normal path and compensates for the rest - partial degradation.
Single specialist fails. Same pattern, simpler case. Failure status, original prompt, takeover instruction. Parent answers directly.
Why this matters
In a team, the leader doesn't just relay status reports. When a team member is unavailable, the leader either reassigns the work or does it themselves. They own the outcome, not just the delegation. Engineers call this the supervisor pattern - the supervisor is responsible for the result, regardless of whether its workers delivered.
The previous system was just a message relay. "The specialist said X" or "the specialist failed." The new system is actual leadership. The parent agent is accountable for giving you an answer, whether or not the specialists are available. The specialists are an optimisation (faster, more focused responses from domain-tuned models), not a dependency the system falls apart without.
This is also related to what microservice architects call the bulkhead pattern - named after the watertight compartments in a ship's hull. If one compartment floods, the others stay dry. A specialist timing out doesn't sink the user's entire request. The parent absorbs the failure and the ship keeps sailing.
The implementation detail that matters
Each failed agent's entry includes its name, ID, and why it failed (error, timeout, no_result, budget_exhausted). This serves two purposes: it gives the parent model structured context to understand what went wrong, and it creates an audit trail so both the user and the system logs know exactly what happened. No ambiguity about which specialist was unavailable or why.
For parallel execution (when you fan out to multiple specialists at once and then fan in the results), the takeover only fires for the agents that actually failed. If you dispatched three specialists and one timed out, you get two specialist responses plus the parent's direct answer for the third. The collector separates successes from failures and only generates takeover directives for the failed ones. Clean separation.
What Claude did here
I described the problem: "when sub-agents fail, the parent just gives up." Claude understood immediately that this was about accountability in a hierarchical system, not just error handling. We designed the takeover directive format together, iterated on the detection logic, and Claude wrote the implementation including the tricky partial-failure case where some agents succeed and some don't. The prompt wording for the parent's instructions - telling it to take ownership rather than apologise - was a back-and-forth between us until it hit the right balance. Claude also flagged the need for a negative test: verifying that takeover does NOT fire when all agents succeed. Good catch - you always need to test that your safety net doesn't activate when everything is fine.