⚠️ Error Handling
dagpipe raises a small, predictable set of exceptions. Know when they surface and how to react.
📋 Exception reference
| Exception | Raised when | Where |
|---|---|---|
SchemaError |
Payload violates the declared schema | State.__post_init__, Schema.validate_payload, Schema.validate_update, Schema._walk, Schema._check_type, Schema._validate_path |
TypeError |
resolve()/resolve_async() yields a non-State |
Node.run, AsyncNode.run_async |
TypeError |
Engine(...) receives a non-Node element or a non-Sequence/Graph |
Engine.__init__ |
TypeError |
Engine.run/run_async receives a non-State root |
Engine.run, Engine.run_async |
TypeError |
Graph.add_edge/add_root receives a non-Node |
Graph.add_edge, Graph.add_root |
TypeError |
A YAML node class path is not a Node subclass |
_load_nodes |
ValueError |
Adding an edge would create a cycle (incl. self-cycle) | Graph.add_edge |
ValueError |
Node.id is not valid dotted snake_case |
Node.clean_id_and_name |
RuntimeError |
Engine mode is corrupt (should never happen) | Engine.run |
🧊 Schema failures
Guidance:
- A
SchemaErrorduring construction means the root can never exist — fail the request/concept early. SchemaErrorduringfork(payload_update=...)means the update path was not declared — fix the schema or the update, don't swallow it.
🔁 Cycle failures
Cycles (including a → a) always raise immediately at wiring time, never at
execution. Treat them as a design error: redraw the topology.
🧬 Bad node output
This check is applied per yielded object, so one bad element in a generator
fails the whole run.
🪜 Step-wise status, not errors
run_steps doesn't raise when a node produces no output — it reports
completed=False:
Treat completed=False as a signal, not an exception. See
use case 07.
💡 Handling strategies
- At the boundary: construct states/pipelines in a wrapper that converts
SchemaErrorinto a user-facing4xx(API) or a descriptiveFAILEDstatus (batch jobs). - At the graph: let
ValueErrorfromadd_edgepropagate during setup — it's a programming error you want to see in CI. - Never catch
State/Payloaderrors mid-pipeline and continue with a fallback payload — the pipeline was designed to enforce invariants.
📚 Read Next
- Best Practices — design rules that avoid these errors.
- 04 – Schema and payload — validation details.
- 07 – Testing example — asserting on error paths.