Skip to content

Commit d008938

Browse files
committed
docs(flows): split the subflow-strand paragraph into its three cases
The paragraph conflated three outcomes of a paused subflow chain into one prose block, and its closing sentence ("an ancestor is never stranded, because resuming it is not what moves it") was written for the child-strand case only. #15556 (PR #17908, merged c8a006f) shipped a third case the paragraph never described: the child completes, bubbleToParent resumes the parent, and the parent's own downstream node throws — the parent itself lands on the engine's 'stranded' exit and is reported on resumeFailure. Measured against origin/main a88a1bb: - packages/services/service-automation/src/engine.ts:1737 (SubflowParentStrand), :7434 (the 'stranded' exit bubbleToParent records it on) - packages/plugins/plugin-approvals/src/approval-service.ts:3476 (the resumeFailure shape: RESUME_FAILED / stranded / repairable)
1 parent a88a1bb commit d008938

1 file changed

Lines changed: 24 additions & 11 deletions

File tree

‎content/docs/automation/flows.mdx‎

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,17 +1102,30 @@ the chain resolves from either end:
11021102
parked on an `approval`, resuming the parent is refused too.
11031103

11041104
A child that fails terminally after the pause fails every waiting ancestor, so
1105-
no run is stranded as resumable-forever. **When the child's failure is a
1106-
strand** — its resume consumed the pause and a downstream node threw — each
1107-
ancestor's consumed pause is recorded too, and the repair verb puts the whole
1108-
chain back in one call: `POST …/runs/{runId}/restore-suspension` on **any**
1109-
member re-arms every member, deepest first, so the continuation re-issued on
1110-
the run you named flows back up through the ancestors instead of completing a
1111-
leaf into a parent that never continues. Re-arming an ancestor is all the verb
1112-
does — an ancestor is never *stranded*, because resuming it is not what moves
1113-
it. A cascade from a child that is **not** repairable records no ancestor
1114-
snapshot, deliberately, so the verb never promises a chain repair it could not
1115-
finish.
1105+
no run is stranded as resumable-forever — that sentence is scoped to exactly
1106+
this case, not the two below it. **When the child's failure is a strand** —
1107+
its resume consumed the pause and a downstream node threw — each ancestor's
1108+
consumed pause is recorded too, and the repair verb puts the whole chain back
1109+
in one call: `POST …/runs/{runId}/restore-suspension` on **any** member
1110+
re-arms every member, deepest first, so the continuation re-issued on the run
1111+
you named flows back up through the ancestors instead of completing a leaf
1112+
into a parent that never continues. Re-arming an ancestor is all the verb does
1113+
in this case — no ancestor is stranded here, because resuming it is not what
1114+
moves it. A cascade from a child that is **not** repairable records no
1115+
ancestor snapshot, deliberately, so the verb never promises a chain repair it
1116+
could not finish.
1117+
1118+
**A third case is the opposite: the bubble itself is what strands an
1119+
ancestor.** The child completes cleanly, `bubbleToParent` resumes the parent
1120+
on the child's behalf, and the parent's own downstream node throws. There the
1121+
bubble — not a resume the caller issued — is exactly what moves the parent, so
1122+
the claim above does not hold for it: the parent lands on the engine's
1123+
`'stranded'` exit, terminal, and repairable only by an operator's
1124+
`restoreConsumedSuspension`. The child's own resume genuinely succeeded, so its
1125+
resumer (an approvals decision door, a wait timer) is told the resume
1126+
succeeded; as of #15556 an approval `decide()` also reports the stranded
1127+
parent on `resumeFailure` (`{ code: 'RESUME_FAILED', runId: '<parent>',
1128+
status: 'stranded', repairable: true }`).
11161129

11171130
See the worked example pair in the showcase app:
11181131
`showcase_project_closure` invokes the reusable `showcase_closure_signoff`

0 commit comments

Comments
 (0)