When a run fails

Triage a failed run: the summary, the state, the failing criterion, then fix, heal or reset.

zurdo v1.36.0

A run exits 5 when a task ends failed (its attempts are spent) or blocked-by-dependency. Work down this list, and stop where the fix is.

  1. Read the summary. Which task failed, and which criteria.
  2. Open the state. zurdo state, the report and the iteration files.
  3. Read the failing criterion. Is the code wrong, or the hint?
  4. Ask the skill. zurdo-hint-debugger decides for you.
  5. Fix, then run again. Heal a misaimed grep hint, or reset.

1. Read the summary

zurdo run docs/greeter/prds/prd-02-changelog.md
═══ Run Summary ═══
  task-changelog       failed                   2/2        154ms        0/2
  task-release         blocked-by-dependency    0/3        —            —
Next: fix root causes and re-run — zurdo run docs/greeter/prds/prd-02-changelog.md
run failed: 1 task(s) failed, 1 blocked-by-dependency

Fix the failed task only. A blocked task has no fault of its own: it was never attempted.

2. Open the state

zurdo state
$ zurdo state list
slug                   prd_path                               last_run              status
prd-02-changelog-6c9f  docs/greeter/prds/prd-02-changelog.md  2026-10-15T06:04:57Z  clean
$ ls "$(zurdo state where docs/greeter/prds/prd-02-changelog.md)"/iterations
task-changelog-1.err  task-changelog-1.out  task-changelog-1.prompt
task-changelog-2.err  task-changelog-2.out  task-changelog-2.prompt

Each attempt keeps the prompt zurdo sent and the agent's stdout and stderr. zurdo report <prd> --format md gives a per-task account, and the zurdo-state-summary skill reads it all back with a recommended next action.

3. Read the failing criterion

Under each ✗ the run printed the hint and the tail of its stderr. Ask one question: would a correct implementation pass this hint?

The code is wrong The hint is right and the agent missed. Read the last .prompt and .out: was the description clear, and was the needed context there?

The hint is wrong The work is done, but the check aims at the wrong file, symbol or pattern. A moved file or renamed function is the usual cause.

A ⚠ stalled line means two attempts failed the same way. More attempts rarely help. With [reason] on, zurdo diagnoses a stall. See Diagnosis & lessons.

4. Ask zurdo-hint-debugger

From your agent CLI, ask the skill why the criterion failed. It correlates the hint with the iteration logs, the current tree and the PRD's .trail.md, then proposes a corrected hint or a corrected code change.

5. Fix, then run again

A plain resume keeps a failed task failed. Pick the path that matches the fix:

task failed grep hint misaimed code fixed by hand PRD edited zurdo heal, run zurdo run --reset task failed grep hint misaimed zurdo heal, run code fixed by hand or PRD edited zurdo run --reset
Only heal reopens a failed task in place. Every other fix goes through a reset.

Heal a misaimed grep hint. zurdo heal <prd> proposes a corrected payload for each failed [grep:] or [no-grep:] hint, verifies it against the live tree, and asks y/N for each. The next zurdo run accepts the edit, sets the healed tasks back to pending with fresh attempts, and resumes. Heal needs [roles.analyzer]. Without a TTY it writes <prd>.proposed.md instead.

Reset for everything else. After you fix the code, or edit the PRD (any byte change makes a plain run exit 4), start over:

zurdo run docs/greeter/prds/prd-02-changelog.md --reset
─── task-changelog: Add a changelog ─── effort=low, deps=[]
  ✓ task-changelog: passed in 0 iterations (—)
─── task-release: Mention the changelog in the greeting help ─── effort=low, deps=[task-changelog]
  → iteration 1 of 3
    ✓ shell: sh greet.sh --help | grep -q CHANGELOG.md
  ✓ task-release: passed in 1 iterations (56ms)
═══ Run Summary ═══
  totals               2 passed, 0 pending-review, 0 failed, 0 blocked     243ms
  passed-at-preflight  2 criteria — proved nothing about this run
The hand-fixed task passes at pre-flight. The old state is archived, not deleted.

Reset moves the old state to .zurdo/<slug>/.archive/<timestamp>/ and runs every task again. Work that's already on the tree passes at pre-flight for free, and is flagged as proving nothing about this run.

If the same task keeps failing after a fix, the scope's model of the system is probably wrong. Take it back to the loop. For stall diagnosis and the lessons a fix leaves behind, see Diagnosis & lessons.