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): an onFail max of 1 never recovers, and recoveries come one short of max #1542
max is documented (README, "Failure recovery") as the number of recovery attempts: "with max from 1 to 8 (default 3). When the node fails and recovery attempts remain, the workflow resets to the recovery target and runs through the failing node again. After max recovery attempts, the node fails permanently and the run stops." cleanEdge() also accepts max: 1 for an onFail edge.
With ran >= max the number of recoveries is max - 1, and max: 1 is a dead value: the first failure is already 1 >= 1, the recovery edge is skipped, the node fails permanently on its first attempt, and failAttempts stays empty — indistinguishable, field by field, from a node that has no recovery edge at all.
Reproduction (measured on d6410d07)
Two-node graph draft → review, plus review → draft with { onFail: true, max }, failNode(review, { failAttempts: {} }):
So max: 1 behaves like "no edge", while max: 2 gives one recovery — one fewer than the README promises.
Expected
max is the number of recoveries, so max: 1 recovers exactly once, max: 2 twice, and after the last recovery the next failure is permanent with failAttempts recorded at max.
Scope
failRecoveryDecision() only: compare ran > max instead of ran >= max. One line.
loopDecision() keeps ran >= max: for a loop edge max means total executions of the loop body (max: 1 runs it once), which is the correct semantics and stays untouched. A short comment records that the same field means different things on the two edge kinds.
cleanEdge() keeps accepting 1–8 — max: 1 becomes meaningful instead of being rejected.
Wording: the README sentence and changelog.d/1526.added.md ("up to 3 times total" → "up to three recoveries") are aligned with the code in the same change.
Tests: max: 1 recovers once and records failAttempts = 1; after max recoveries the next failure is permanent and failAttempts stops at max; a max: 2 counting case. Each must fail on the base tree.
Out of scope
The recovery body itself (failNode's loopBody argument order — a separate defect), the Settings authoring surface for onFail edges (none exists), and showing n/max in the run log / publicRun() (observability, 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: 8ac9af64cd044b0f8c53a701873727e5
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.