7.9 Debugging a pipeline
Pipelines fail in a few characteristic ways, and the runtime gives you targeted tools for each. This is the workflow to reach for when a flow doesn't do what you expected.
1. Confirm what was actually stored — ?$plan
Especially after authoring in the DSL, the first question is "did the runtime store the spec I meant?"
GET /<mount>/.pipelines/<spec>?$plan
Read the canonicalized pipeline (the typed form) and the plan.warnings. A
surprising structure here — a step that landed in the wrong place, a condition
that didn't attach — explains a lot before you run anything. Also heed the
segment warnings (7.8): an unsafe step mid-segment is a retry hazard.
2. Bisect with ?$to-step
Run the pipeline but stop after top-level step N:
… ?$to-step=0 # run only through step 0
… ?$to-step=1 # … through step 1
Walk it forward until the output goes wrong; the step where it breaks is your culprit. This is the fastest way to localize a failure in a long serial flow.
3. Read the structured failure
A pipeline failure merges a pipeline object into the problem+json body
(9.2):
{ "code": "...", "status": 502,
"pipeline": {
"failedStep": "/2",
"steps": [
{ "step": "/0", "kind": "call", "status": 200 },
{ "step": "/1", "kind": "transform", "status": 200 },
{ "step": "/2", "kind": "call", "status": 502 }
] } }
failedStep— the index path of the step that failed ("/2"; nested subpipeline paths look like"/3/steps/…").steps— each executed step with its status, so you can see how far it got and what each returned.
4. Remember: conditions skip silently
The most common "it didn't run" confusion isn't an error at all. A step with a
false if, or any step sitting after an end/onSucceed: end, is skipped
silently — it simply doesn't appear to have executed. If a step seems to do
nothing:
- check its
ifcondition (is it actually true at that point?), - check whether an earlier step's
endaction exited the pipeline first, - in
conditionalmode, remember only the first matching step runs.
A quick checklist
| Symptom | First check |
|---|---|
| Stored spec looks wrong | ?$plan — the canonicalized typed form |
| Output wrong partway through | ?$to-step=N to bisect |
| A request 4xx/5xx'd | pipeline.failedStep + per-step statuses in the body |
| A step "didn't run" | its if, a prior end, or conditional-mode semantics |
| An effect fired twice on retry | segment warnings in ?$plan; mark it keyed |
The next two sections cover two practical applications of that machinery: fixed wrappers and event-triggered flows.
← Previous: 7.8 Segments and ?$plan · Manual home · Next: 7.10 Wrappers and response shaping →