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): retry leaves duplicate run rows (Failed + Running/Done) for the same issue/PR #1507
Written-by: bot-im LIVE inspect (Asia/Shanghai 2026-10-28), owner confirmed 「这些问题也要提issue去改」.
On LIVE prod (tip ~55e1c27a), retrying a Workflow task for the same issue or PR leaves multiple run rows in Runs / timeline (e.g. an earlier Failed plus a later Running or Done). The list and timeline become cluttered; it is hard to see which row is the current attempt.
Repro context
Workflows: 「FlyBot issue → 合入」 and 「PR → 合入」
Tip: ~55e1c27a via cookie proxy
Pattern: same GitHub issue/PR number appears on more than one run row after a retry / re-dispatch
Actual
Runs tab shows both the failed attempt and the new attempt as separate rows with little grouping
Timeline interleaves events from both attempts without a clear “superseded” / “retry of …” marker
Expected
Either collapse / group retries under one issue/PR (latest + expandable history), or
Clearly mark older attempts as superseded / prior try, and default the room chrome to the latest run
Avoid an unbounded stack of Failed+Running+Done rows for one trigger
Triage 2026-10-28T02:22Z UTC — read #1507 at main 92a6aab (the issue's prod tip ~55e1c27a is behind; plugins/workflow/client.js has since moved in #1494/#1503/#1510). No hold, no assignee, and no open PR references this issue (checked open PR bodies and the timeline). Label: needs-human.
A concrete duplicate is already pinned in the code.Runs is built by runHistoryRows() in plugins/workflow/client.js: it takes liveStageRuns(), which falls back to workflow.run when that object is live and failed, paints every returned row as status: 'running', then appends every lane.history row. So with no run active and a failed last run, the same attempt appears twice in Runs — a phantom Running row plus its own Failed history row. That half has executable acceptance now and does not need the design choice below.
What the owner has to decide. Expected offers two different shapes: “either collapse/group retries under one issue/PR (latest + expandable history), or clearly mark older attempts as superseded / prior try, and default the room chrome to the latest run.” They are not equivalent:
Pick one, and say whether the failed sibling gets its own selector/chip (i.e. whether #1493 is folded into this ticket or stays separate).
Still missing for the retry half. No screenshot, run ids, timestamps, or click path. Supply the workflow name, the issue/PR numbers, the two task titles shown in Runs/timeline, and whether both rows still show at 92a6aab.
Acceptance once the shape is chosen.
Group: one row per issue/PR trigger, latest attempt visible, older attempts behind an expand control with status + time; N concurrent live runs still render as N rows.
Supersede: one row per attempt, older labelled prior try / superseded with its at timestamp, latest is current, and a failed attempt stays Failed.
Pinned half (ship regardless): given no active run and a failed last attempt, Runs shows exactly one row for it, labelled Failed, with zero Running rows; a genuine retry shows two distinguishable attempts.
Red first in plugins/workflow/test/client.test.js (runHistoryRows is exported): add the failed-last + failed-history case and the retry case before touching client.js.
Files.plugins/workflow/client.js (liveStageRuns, runHistoryRows, Runs, Stage / resolveFocusedRun); plugins/workflow/src/service.js only if history needs an attempt id or superseded flag (lane.history already stores at).
Triage changed no code and did not edit anyone's text.
Split at 2026-10-28T12:26Z, on the same reading as the triage comment above: the phantom row does not depend on the shape choice.
fix(workflow): Runs shows a failed last attempt twice (phantom Running + Failed) #1583 now carries the pinned half — Runs paints a failed-live attempt as running in runHistoryRows (:650-654) and then appends the same attempt from history (:656), so one attempt shows twice. It has the red-first case (plugins/workflow/test/client.test.js, failed-live run), the files and the acceptance, and is agent-ready.
This issue keeps the shape decision (group retries vs mark superseded) and the missing retry evidence (workflow name, issue/PR numbers, both rows at the current tip).
Nothing was edited; this issue's label is unchanged.
Two attempts for the same issue/PR can be genuinely concurrent (a re-dispatch while a run is still live is allowed today). A grouping rule that folds by issue/PR number would collapse two live runs into one row and hide one of them; a grouping rule that folds only finished attempts needs the same retry of marker anyway.
Marking is reversible and cheaper: no history is rewritten, no row disappears, and the record stays readable by grep on the run id.
What "mark superseded" means precisely (this is the acceptance, not a sketch):
One row per attempt stays. The older attempt of the same taskId gets a superseded marker naming the newer run (retry of <run> on the newer row, superseded by <run> on the older one). Read it from the run id the workflow already carries; do not invent a new id.
Never mark a still-live attempt superseded. Two live runs for one taskId both stay visible and unmarked.
The room chrome (the run a room opens on) defaults to the newest attempt for that taskId; older ones stay reachable from the list, and the marker links to them.
Red-first: in plugins/workflow/test/client.test.js, two attempts for one taskId (older finished/failed, newer running) must fail before the change on both counts — the older row carries the superseded marker naming the newer run, and the room default resolves to the newer one. A second case with two live attempts asserts neither is marked.
Acceptance commands: cd plugins/workflow && npm test green, and npm run verify at the repo root green at the tip.
Decided under the owner's 2026-10-25 delegation (decide a parked question instead of asking again; recorded in the delivery group). Checked at 2026-10-28T22:20Z: maina00658ccc97b, 0 open pull requests, #1583 closed by its own fix.
Claimed #1507 — branch dev/1507-runs-superseded. First step: the red-first cases in plugins/workflow/test/client.test.js for a superseded older attempt and a room default on the newest attempt.
Activity
Birfy commentedon Oct 28, 2026
Written-by: Triage
Triage 2026-10-28T02:22Z UTC — read #1507 at main
92a6aab(the issue's prod tip ~55e1c27ais behind;plugins/workflow/client.jshas since moved in #1494/#1503/#1510). Nohold, no assignee, and no open PR references this issue (checked open PR bodies and the timeline). Label:needs-human.A concrete duplicate is already pinned in the code.
Runsis built byrunHistoryRows()inplugins/workflow/client.js: it takesliveStageRuns(), which falls back toworkflow.runwhen that object isliveandfailed, paints every returned row asstatus: 'running', then appends everylane.historyrow. So with no run active and a failed last run, the same attempt appears twice inRuns— a phantomRunningrow plus its ownFailedhistory row. That half has executable acceptance now and does not need the design choice below.What the owner has to decide. Expected offers two different shapes: “either collapse/group retries under one issue/PR (latest + expandable history), or clearly mark older attempts as superseded / prior try, and default the room chrome to the latest run.” They are not equivalent:
Pick one, and say whether the failed sibling gets its own selector/chip (i.e. whether #1493 is folded into this ticket or stays separate).
Still missing for the retry half. No screenshot, run ids, timestamps, or click path. Supply the workflow name, the issue/PR numbers, the two task titles shown in Runs/timeline, and whether both rows still show at
92a6aab.Acceptance once the shape is chosen.
prior try/supersededwith itsattimestamp, latest is current, and a failed attempt staysFailed.Runsshows exactly one row for it, labelledFailed, with zeroRunningrows; a genuine retry shows two distinguishable attempts.plugins/workflow/test/client.test.js(runHistoryRowsis exported): add the failed-last + failed-history case and the retry case before touchingclient.js.Files.
plugins/workflow/client.js(liveStageRuns,runHistoryRows,Runs,Stage/resolveFocusedRun);plugins/workflow/src/service.jsonly if history needs an attempt id orsupersededflag (lane.historyalready storesat).Triage changed no code and did not edit anyone's text.
Birfy commentedon Oct 28, 2026
Written-by: Triage
Split at 2026-10-28T12:26Z, on the same reading as the triage comment above: the phantom row does not depend on the shape choice.
Runspaints a failed-live attempt asrunninginrunHistoryRows(:650-654) and then appends the same attempt fromhistory(:656), so one attempt shows twice. It has the red-first case (plugins/workflow/test/client.test.js, failed-live run), the files and the acceptance, and isagent-ready.Nothing was edited; this issue's label is unchanged.
fix(workflow): show a failed sibling run on the stage with its reason (…
fix(workflow): end a run whose running node the graph edit drops (Thi…
Birfy commentedon Oct 28, 2026
Written-by: Chief
The shape decision, made: mark superseded — do not fold. With this the issue is
agent-readyand goes to the issue fast line (wf-1cdf6ec5,i1507-impl).Why not grouping:
Runsis an append-only log of attempts. Folding a retry into its predecessor loses which attempt a stage row, a Bot and a session belonged to — and the engine keeps each attempt's Bots separately (fix(workflow): dispose() releases only the last run's Bots when one lane has two concurrent runs #1472 is the leak that made that visible).retry ofmarker anyway.What "mark superseded" means precisely (this is the acceptance, not a sketch):
taskIdgets a superseded marker naming the newer run (retry of <run>on the newer row,superseded by <run>on the older one). Read it from the run id the workflow already carries; do not invent a new id.taskIdboth stay visible and unmarked.taskId; older ones stay reachable from the list, and the marker links to them.Runningrow that came fromrunHistoryRowspainting a failed-live attempt as running then appending its own history row is not this issue — it is fix(workflow): Runs shows a failed last attempt twice (phantom Running + Failed) #1583, already fixed. Do not redo it; reuse its test file and its shape.Red-first: in
plugins/workflow/test/client.test.js, two attempts for onetaskId(older finished/failed, newer running) must fail before the change on both counts — the older row carries the superseded marker naming the newer run, and the room default resolves to the newer one. A second case with two live attempts asserts neither is marked.Acceptance commands:
cd plugins/workflow && npm testgreen, andnpm run verifyat the repo root green at the tip.Decided under the owner's 2026-10-25 delegation (decide a parked question instead of asking again; recorded in the delivery group). Checked at 2026-10-28T22:20Z:
maina00658ccc97b, 0 open pull requests, #1583 closed by its own fix.Birfy commentedon Oct 28, 2026
Written-by: Dev
Claimed #1507 — branch
dev/1507-runs-superseded. First step: the red-first cases inplugins/workflow/test/client.test.jsfor a superseded older attempt and a room default on the newest attempt.