Vibestrate
Vibestrate
docs

Debug a failed run

How to figure out why a run ended in failed or blocked, and what to do next.

In simple words

When a task does not finish cleanly, this guide helps you find out why. The run screen in Mission Control surfaces the same evidence; the commands and paths below are the automation path.

Start by reading the status, because failed and blocked mean different things and need different responses:

failed A step crashed. Read that step’s own output - it says what broke.

blocked Something refused: a review, a policy, or a failed check. Read the decision.

Tip

vibe replay <runId> is the fastest first move for either. It reopens the finished run with every decision, output and artifact in place, so you read what happened rather than reconstructing it. The run screen’s Replay tab is the same.

Where to look

The failing step’s output For failed. Usually a stack trace or a command that exited non-zero.

The review finding For blocked on review. It says what it objected to and why.

The validation output For a failed check. Your own commands, your own error.

The worktree Still on disk. Open it and read the half-finished work.

Did you know

A run that ends badly keeps its worktree on purpose. Nothing is cleaned up on failure, so the evidence is there when you come back tomorrow.

Start with replay

Open the run. When it ended badly the Outcome banner is the first thing on the screen: a red card that names what happened, says why in a sentence, and puts the next move on a button - Re-run with changes, See review, View events or View diff, whichever fits the ending.

That is usually enough. When you want the whole record, the Inspect section’s Replay tab walks the run start to finish, and Artifacts lists everything it wrote before it stopped.

From a terminal:

vibe replay <runId>

Read-only either way: you can look but not change anything. The status line says which stage threw, and the artifact list shows what the run recorded before it stopped.

If status is failed

A failed status means a stage raised an error it could not recover from. Four things to look at:

  1. events.ndjson - the last event before the failure shows which transition triggered the error.

  2. The step’s output at .vibestrate/runs/<runId>/artifacts/flows/<step-id>/output.md - the model’s last response for that step, and any tool-use error. <step-id> is the step’s own name in the flow, like plan or review.

  3. The validation output at .vibestrate/runs/<runId>/artifacts/flows/<step-id>/validation-results.json - the exit codes, if the failure happened during validation. The stdout and stderr per command sit alongside under validation/.

  4. The step’s context packet at .vibestrate/runs/<runId>/artifacts/flows/<step-id>/context-packet.json - what the step was given: each input marked whole, summarized or unavailable, the token budget, any required input that was missing (contractViolations; a run that stops with Flow step "review" cannot run: ... is this), and anything the supervisor added (injections).

The run screen’s Events, Artifacts and Validation inspector tabs read the first three of those files.

Common causes:

Provider not authenticated - vibe provider test <id> confirms the local CLI running the model is connected; the Crew page’s Providers tab has the same test.

Validation command missing - check commands.validate in .vibestrate/project.yml.

Worktree creation failed - one common case: git.requireCleanMain is on and main has uncommitted changes.

Skill referenced doesn’t exist - check vibe skills list.

If status is blocked

blocked is not a crash: it means a decision is needed. Start by reading:

  1. artifacts/flows/review/output.md - the reviewer’s findings and the rationale behind its decision. In the default flow those findings go straight back to the implementer for another pass; deep routes them to a dedicated fixer.
  2. artifacts/flows/verify/output.md - the verifier’s summary, on a flow that has a verify step. The default flow has none; deep does.

Either way, events.ndjson carries the matching review.decision or verification.decision event with the verdict.

Then act on what you find. The right answer is rarely “rerun and hope”:

Sharpen the task - edit the task description to be more specific.

Teach a rule - add a skill encoding the rule the agent did not know.

Tighten permissions - adjust a permission profile if the agent reached for something it should not.

Drop the scope - split the work into two smaller tasks.

Re-run after fixing

Re-run with changes, on the Outcome banner, opens a dialog with this run’s brief already in it, so you edit the task rather than retype it. A Start from picker decides how much to keep, worded by what each choice reuses: “Beginning - re-plan from scratch”, “Architecture - reuse the plan”, “Implementation - reuse plan + architecture”, then Review, Fix and Verify, which each restore this run’s code. Stages the run never reached stay visible but cannot be picked.

Every run is a fresh run with a fresh runId, and past runs stay at .vibestrate/runs/. Nothing is overwritten, so the failed one is still there to read - open either from the Runs page and compare their Artifacts side by side.

From a terminal, the same comparison on disk:

cd .vibestrate/runs
diff <oldRunId>/artifacts/flows/plan/output.md \
     <newRunId>/artifacts/flows/plan/output.md

Rewind instead of restarting

Sometimes only the implementation needs another pass - the run was read-only, say, and you now want the executor to write code. Rewind forks a fresh run that reuses the earlier artifacts and resumes from a stage you pick, so you do not re-pay for planning:

# executing     reuse the plan (plus architecture, on `deep`)
# architecting  reuse just the plan (`deep`)
# planning      seed nothing, start over
vibe run "<same task>" --resume-from <oldRunId> \
  --resume-stage executing

--resume-stage takes six values and defaults to executing:

planningarchitectingexecutingreviewingfixingverifying

The first three regenerate the code. The last three need the earlier code back, which is the next section.

The flow runner finds the first step at the stage you named, seeds the outputs of every earlier step from the source run (marking them skipped (resumed) in the step ledger), and starts there. The forked run gets its own runId and a fresh worktree off your main branch; the original is untouched, its lineage recorded under resumedFrom in state.json.

This works with --flow too: any flow declaring the matching step stage can be resumed. The default flow declares planning, executing and reviewing; architecting, fixing and verifying belong to deep, and resuming at a stage the flow has no step for is refused.

Rewinding to review, fix or verify

reviewing, fixing and verifying need the executor’s code already in place, so Vibestrate first restores the source run’s per-phase worktree snapshot into the fresh worktree.

A snapshot is a saved copy of the run’s code at a point in time. Only runs that captured one - every run that produced code - can be rewound this way, and both the CLI and the dashboard say when there is none.

Because that restore overwrites and removes files, dry-run it first to see the exact blast radius:

vibe run "<same task>" --resume-from <oldRunId> \
  --resume-stage reviewing --preview

--preview prints the overwrite and remove set and exits without starting a run. The same data is at GET /api/runs/<id>/restore-preview?stage=reviewing, and the Re-run with changes dialog shows a live preview panel when you pick a downstream stage.

The restore is bounded: it only ever runs against a real, isolated run worktree, never your own checkout. A failed or refused restore marks the run unsafe in its assurance verdict instead of letting it pass as verified.

Pruning snapshots

Each rewind-able run anchors its code as a git ref under refs/vibestrate/snapshots/, which slowly grows your .git, and Vibestrate never deletes these on its own.

The Runs page has a Prune snapshots button for the common case: it clears the orphans - runs whose directory is gone - and previews before it deletes. For hands-off trimming, set git.snapshotRetentionRuns on More > Config to keep the last N runs.

Only refs are ever removed. Artifacts and branches are untouched.

From a terminal, where the narrower targets live:

vibe runs prune                # orphans
vibe runs prune --keep 20      # keep newest 20
vibe runs prune --run <id>     # just this run
vibe runs prune --orphans --dry-run   # preview

It prints the plan and asks before deleting; -y skips the prompt.

When to file a bug

If the same task fails in the same place across multiple providers, and the failure is not traceable to your config or task description, that is worth a bug report. Include the runId, the events.ndjson excerpt around the failure, and the failing step’s output.md.

© 2026 Vibestrate
v0.4.3 Shonshon - Evolving Technologies