Skip to content

Errors & retries

Agent runs are flaky in ways pure code is not. A CLI hiccups, a model returns nothing, a tool call times out. threadle gives every node its own failure policy.


A node that throws marks itself error and stops the run. Nodes already finished keep their results. Queued nodes never start.

That’s the right default for a pipeline where step three depends on step two being correct.


Right-click a node → retry: off, 1×, or 3×.

Retries use a short backoff between attempts, and each attempt is logged:

⟳ implement failed (attempt 1/4) — retrying: CLI exited 1

Retry is worth it for transient failures (network, rate limits) and pointless for deterministic ones (a bad model name, an unwired input).


Right-click a node → continue on error. On final failure the node goes red, the run keeps going, and anything downstream of it starves. Those nodes are skipped because their input never arrived.

⤼ review failed after 2 attempts — continuing: …
∅ output starved (upstream muted/failed) — skipped

Use it for optional branches: a nice-to-have summary that shouldn’t sink the run that produced the actual work.


A prompt feeds an agent. Success leaves on the upper out port to a happy-path output. After retries fail, failure text leaves on the lower red out port to a fallback convert and err output.

Upper out is the happy path. Lower red err (out:err) carries failure text after retries. Wire it for a fallback arm.

Agent-def nodes expose a second out on the right edge. The error connector:

Handle idout:err (graph JSON)
CanvasLower red port · red wire when connected
Hovererr · after retries exhausted
EmitsFailure text after retries are done

Behavior:

  • Wired err: failure text goes to that arm. The run continues (happy-path downstream starves).
  • Unwired err: abort the run, or starve if continue-on-error is set.

This is for fallback arms (convert → output, Judge → fix, human gate), not for skipping work silently.

Prefer out:err over bare continue-on-error when you still want a recovery path. Graph lint warns if continue-on-error is on and out:err is empty.

Terminal window
threadle run agent-err-fallback

A starved node is idle, not errored. threadle distinguishes:

StateMeaning
errorThis node ran and failed
idle (starved)This node never ran. Its inputs never arrived
idle (muted)You told it to skip

This matters when reading a run log: a wall of skipped nodes usually has exactly one red node at its head.


When a subscription model pool is spent, the run log shows a ! line (not just raw CLI stderr):

! model usage exhausted (7d) — resets Tue 14:00 · pick another model on the agent, or wait for reset
! model usage exhausted (Other Models pool) — pick another model on the agent, raise Spending limits, or wait for the monthly reset
SourceHow threadle knows
ClaudeCached 5h / 7d / Opus 7d utilization in ~/.claude.json. Preflight at 100%, or classify CLI text
CursorCLI error strings only (monthly Spending pools. No local % mirror)

Retry won’t help until the window resets or you change model / limits. Prefer picking another model on the agent-def card.

See Costs · Plan & utilization · Agents.


Per-node policy handles individual nodes. The retries circuit breaker mode watches the run: it trips once the accumulated failure count crosses a threshold.

“Tolerate two flaky steps, abort on the third” is a single node.


Stopping a run (or closing a canvas run) leaves no node stuck glowing: anything still queued or running is reset to idle when the run ends. Detached runs survive the browser entirely. See Detached runs.


  • Run log. Full per-node detail, including stderr excerpts from custom nodes
  • Runs view. One row per run with status and error
  • The node itself. Status persists on the graph after a detached run, so you can open it later and see what went red