Structural Validation
Structural errors (DIP001–DIP010) — the 10 checks a workflow must pass to run.
Overview
Dippin provides two levels of analysis:
Structural validation (DIP001-DIP010): Errors that must be fixed. A workflow with any of these cannot execute. Run with dippin validate.
Semantic linting (DIP101-DIP162): Warnings that flag likely bugs or questionable patterns. They don’t block execution but should be reviewed. Run with dippin lint for both levels.
Diagnostic Format
Diagnostics are displayed in a rustc-inspired format:
error[DIP003]: unknown node reference "InterpretX" in edge
--> pipeline.dip:45:5
= help: did you mean "Interpret"?Structural Errors (DIP001-DIP010)
These must be fixed for a workflow to be valid. Each causes exit code 1.
The workflow must declare a start: field pointing to an existing node.
error[DIP001]: start node does not exist --> pipeline.dip:1:1 = help: add "start: <NodeID>" to the workflow header
The workflow must declare an exit: field pointing to an existing node.
error[DIP002]: exit node does not exist --> pipeline.dip:1:1 = help: add "exit: <NodeID>" to the workflow header
Every edge's From and To must reference existing node IDs. The validator uses Levenshtein distance to suggest corrections for typos.
error[DIP003]: unknown node reference "InterpretX" in edge --> pipeline.dip:45:5 = help: did you mean "Interpret"?
Every node must be reachable from the start node via some path of edges. BFS from the start node cannot reach this node.
error[DIP004]: node unreachable from start --> pipeline.dip:20:3 = help: add an edge leading to this node, or remove it
The workflow graph must be a DAG, with the exception of restart edges. A back-edge not marked restart: true would loop forever.
error[DIP005]: unconditional cycle detected --> pipeline.dip:50:5 = help: remove an edge in this cycle or mark it "restart: true"
The exit node is the terminal — it must have zero outgoing edges.
error[DIP006]: exit node has outgoing edges --> pipeline.dip:55:5 = help: remove outgoing edges from the exit node
Every parallel node must have a matching fan_in node with the same set of branch nodes.
error[DIP007]: parallel fan-out/fan-in mismatch --> pipeline.dip:15:3 = help: add a matching fan_in node
Node IDs must be globally unique within a workflow.
error[DIP008]: duplicate node ID --> pipeline.dip:30:3 = help: rename this node or remove the duplicate
No two edges may have the same (from, to, condition) combination. Edges with different conditions on the same pair are not duplicates.
error[DIP009]: duplicate edge --> pipeline.dip:60:5 = help: remove the duplicate edge
Every edge when condition must parse into a valid expression. An unparseable condition — an unknown operator, or a tool-node field like marker_grep used in operator position — leaves the edge's routing undefined, so the workflow cannot execute. One diagnostic fires per bad edge; every parseable edge is still checked.
error[DIP010]: edge A -> Z: invalid condition "marker_grep \"^ok\"": unknown operator "^ok" --> pipeline.dip:14:5 = help: valid operators: = == != contains startswith endswith in