Detect and respond to multi-agent failures
Unlock the complete study guide.
Bundled into the existing Developing in Agentic AI Systems premium course — no separate purchase.
14-day money-back guarantee — no questions asked.
Included in this chapter:
- What counts as a failure when the session ended cleanly
- Attributing a failure to the layer that produced it
- Stop hooks: corrective continuation and its guard rails
- Rewriting what a finished worker returns
- Three signals that can look like failures without being one
- Making failure legible to automation
- Degraded output: fixing the assignment, the instructions, or the environment
- Targeted retries: replay the smallest unit that failed
- Steering a live session, and when steering is not available
- Stopping work, and what stopping deliberately does not undo
- Rolling back editor changes with a checkpoint
- Abandoning an in-progress merge of agent branches
- Human-in-the-loop recovery on the agent's pull request
- Reading a recovery scenario under exam conditions
Signal, correct move, and the thing that move does not accomplish
| Situation | The signal you actually have | Correct move | What it does not do |
|---|---|---|---|
| Session ended, work looks partial | `sessionEnd` `reason` (under cloud agent: `complete` / `error` / `timeout`) | Inspect the changed files and run the tests before accepting | The reason value never reports whether the assignment was completed |
| Errors reaching one shared alert queue | `errorOccurred` `errorContext` + `recoverable` | Branch on the context so model, tool, system and user-input failures alert their own owners | It does not stop the run — `errorOccurred` output is not processed |
| Worker repeats the same failing tool call | `postToolUseFailure` `toolName`, `toolArgs`, `error` | Return `additionalContext` (exit code `2` for a command hook) with operation-specific guidance | It cannot prevent the call; `preToolUse` is the pre-execution decision point |
| Agent pull request shows no checks and awaits workflow approval | A pending workflow approval in the merge box | Inspect the proposed changes before selecting **Approve and run workflows** in the merge box | Editing workflow triggers or reassigning the issue does not clear the approval gate |
| `@copilot` correction was ignored | No eyes reaction, no 'Copilot started work' event | Check commenter write access and that the pull request is open; if the pull request is assigned to Copilot, also check the assignment | Missing acknowledgement does not rule out a stall; if comment-triggered work remains stuck, try adding the same comment again |
| `UNKNOWN STEP` appears in the run log | A log line the CLI could not tie to a step | Read the run or job details for the steps the job actually ran | It is not evidence that an undeclared step executed |
| Supervising script proceeds past a failed run | `gh run watch` returning on completion | Add `--exit-status` so a failed run exits non-zero | `--compact` and `--interval` change the display, not the exit status |
| SDK dashboard marks a worker green too early | `subagent.selected` / `.started` / `.completed` / `.failed` | Treat `subagent.completed` as success and handle `subagent.failed` explicitly | `subagent.selected` and `.deselected` say nothing about the result |
| Workers keep returning mis-scoped changes | Repeated incomplete or irrelevant diffs | Rewrite the assignment: problem, acceptance criteria, files to change | Adding more parallel workers does not correct the assignment boundary |
| Workers keep failing the project's CI | Failing first-run checks on agent pushes | Document build, test and validation in `.github/copilot-instructions.md` | Required status checks detect the failure after the push, they do not prevent it |
| Sessions spend their run installing dependencies | Slow or failed trial-and-error discovery | Preinstall in a `copilot-setup-steps` job on the default branch | Leaving discovery to the agent keeps it slow and unreliable in every session |
| A blocked request is suspected | A firewall warning naming the address and the command | Read it in the pull request body (issue-triggered work, a new pull request) or in a comment (comment-triggered work, an existing pull request) | Absence from the location that does not match the trigger does not show the request was not blocked |
| Worker finished with a piece missing | A completion check inside a stop hook | Return `decision: block` with the correction as `reason` for another turn | Under cloud agent the extra turn still counts against the job's existing timeout |
| Corrective loop runs away | `stop_hook_active` on the `agentStop` payload | In an `agentStop` hook, allow the turn when the flag is true so the hook self-limits | Waiting for Copilot CLI's runaway guard is not a substitute for self-limiting the hook |
| Two hooks rewrite one worker response | `modifiedResponse` on `subagentStop` | Do both transformations in one hook and return a single rewrite | Rewrites do not compose; each hook sees the original and the last one wins |
| Running session is heading the wrong way | The prompt box below the session log | Submit a follow-up; it is applied after the current tool call finishes | Steering is unavailable for third-party coding agents |
| One job of many failed | The run's per-job conclusions | `gh run rerun --failed` (downstream dependent jobs included) | A full rerun replays workers that already produced results |
| Failure cause not visible in the logs | Thin first-attempt records | `gh run rerun --debug` for a new attempt with debug logging | No `gh run view` option can create records the attempt never emitted |
| Degraded run must stop, evidence must survive | A run still executing | `gh run cancel` (with `--force` if needed) | Deleting artifacts destroys evidence and stops nothing |
| Cloud session must stop, commits already pushed | **Stop session** in the session log viewer | Stop it, then treat rollback as a separate action | Stopping preserves the pushed commits; archiving only clears the list |
| An editor session took a wrong direction | Per-request checkpoints | Restore the checkpoint for that request | It also removes the later requests from the conversation, and needs checkpoints enabled |
| Agent-branch integration cannot be resolved | An in-progress merge with conflicts | `Git: Abort Merge` to return to the pre-merge state | Accepting one side everywhere discards an agent's work, and marking conflicts resolved without editing them does not itself commit the file; completing the merge requires a separate commit |
| Sensitive work must be done by a human | An open agent pull request with a review thread | Work on the agent's branch and push to the same pull request | Opening a replacement pull request loses the existing review thread |
Decision tree
Cheat sheet
Unlock with Premium — includes all practice exams and the complete study guide.