You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(workflow): failure recovery resets only the two endpoints, not the nodes on the way back #1541
Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: 4c870815318f48acb5325299bb8fff59
Branch: dev4/fix/p78-onfail-recovery-body
Base: a406fee
At: 2026-10-28T03:58:25Z
What happens
plugins/workflow/src/graph.js, failNode()'s recovery branch (around line 661) calls
constbody=loopBody(graph,recovery.edge.to,nodeId)
but loopBody(graph, source, target) (around line 539) means "nodes forward-reachable from target that can still reach source" — the sense completeNode's loop branch uses: loopBody(graph, nodeId, looping.edge.to). With the two arguments reversed the intersections is empty for any recovery target that is not adjacent to the failing node, so body is only the fallback at the end of loopBody:
body.add(source)body.add(target)
The recovery therefore resets the recovery target and the failing node only. Every node between them keeps its done state and its output, so the run re-feeds the same rejected artefact and burns the remaining max without ever producing a different result.
Reproduction (measured on d6410d07)
Graph draft → copy → review, plus review → draft with { onFail: true, max: 3 }; completeNode(draft), completeNode(copy), then failNode(review, { failAttempts: {} }):
now: reset: ["draft","review"], status: { draft:"running", copy:"done", review:"queued" } — copy never leaves done, and after completeNode(draft) again the next failNode still reports failAttempts["review>draft"] = 2 with copy untouched;
with the arguments in the documented order (loopBody(graph, nodeId, recovery.edge.to)): reset: ["draft","copy","review"], status: { draft:"running", copy:"queued", review:"queued" }, which is the README's "runs through the failing node again".
The 2-node shape the current tests use (draft → review) cannot see it: there the fallback's two body.add calls happen to be the whole body.
Expected
A recovery resets the whole segment from the recovery target to the failing node — the target running, the nodes in between queued — so the failing step is reached again with freshly produced input.
Scope
One line in plugins/workflow/src/graph.js: pass the arguments in the documented order. loopBody's contract and the loop branch stay unchanged.
Tests: a ≥3-node chain asserting reset contains the middle node and that it is no longer done; plus one case through service's advance/applyOp asserting the middle node is really dispatched again. Both must fail on the base tree.
The sentence in docs/subsystems/workflow.md describing recovery as resetting "both nodes" and the README line that promises a re-run through the failing node are corrected in the same change.
Out of scope
The max semantics of the recovery edge (a separate defect) and the Settings authoring surface for onFail (no UI entry exists; a separate request).
Label repair at 2026-10-28T11:01:59Z: agent-pr added — this issue's open pull request is #1545 (this repository), head 65860b4e3644125f43dfa646330978447842e8bb. Implementation stays on the pull request line; nothing new starts from this issue.
Replay: the original head is on HugoXK/FlyBot with maintainer_can_modify=false, so we cannot update this branch. The same change (both recovery fixes, both new test files, the corrected README / subsystem-doc wording and the two changelog fragments) is replayed onto current main571be6d4 as #1601 — base main, tip 0b751de611c2879a9b3d19fc06b93dcef1fd9811, 8 files. The original's edit to changelog.d/1526.added.md is dropped: that fragment was consumed by a release on main, and the entry is already in CHANGELOG.md as released history.
The PASS at 65860b4e names this tip and does not carry to the replay, so #1601 needs its own review at its own tip.
This pull request is closed as superseded; #1601 is the one to follow. The issues it fixes stay open until #1601 merges.
Activity
HugoXK commentedon Oct 28, 2026
Claim
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: 4c870815318f48acb5325299bb8fff59
Branch: dev4/fix/p78-onfail-recovery-body
Base: 6202359
Birfy commentedon Oct 28, 2026
Written-by: Triage
Label repair at 2026-10-28T11:01:59Z:
agent-pradded — this issue's open pull request is #1545 (this repository), head65860b4e3644125f43dfa646330978447842e8bb. Implementation stays on the pull request line; nothing new starts from this issue.Birfy commentedon Oct 28, 2026
Written-by: Chief
Replay: the original head is on
HugoXK/FlyBotwithmaintainer_can_modify=false, so we cannot update this branch. The same change (both recovery fixes, both new test files, the corrected README / subsystem-doc wording and the two changelog fragments) is replayed onto currentmain571be6d4as #1601 — basemain, tip0b751de611c2879a9b3d19fc06b93dcef1fd9811, 8 files. The original's edit tochangelog.d/1526.added.mdis dropped: that fragment was consumed by a release onmain, and the entry is already inCHANGELOG.mdas released history.The PASS at
65860b4enames this tip and does not carry to the replay, so #1601 needs its own review at its own tip.This pull request is closed as superseded; #1601 is the one to follow. The issues it fixes stay open until #1601 merges.