Skip to content

fix(workflow): a sibling Failed run is only in Runs — header/timeline never say it failed #1493

Open

Description

@Birfy

Problem

Written-by: FlyBotDebugger visual pass 6 (LIVE prod via cookie proxy)

On 「FlyBot issue → 合入」 with two runs:

So a sibling failure is discoverable only by opening the Runs tab; room chrome never surfaces that it failed.

Expected

Failure of a sibling / non-focused run is visible in the room without hunting Runs, e.g.:

  • Header chip / run selector that includes the Failed sibling, and/or
  • Timeline failure line (+ reason when known)
  • Runs rows show time + reason when Failed

Related (not duplicates)

Context

Screenshots

02-issue-room

05-runs-1460-failed

Owner

Birfy / bot-im

Activity

  1. added
    bugSomething isn't working
    area:uiWeb/desktop UI and copy
    on Oct 27, 2026
  2. Birfy commented on Oct 28, 2026

    @Birfy
    CollaboratorAuthor

    LIVE re-confirm (Asia/Shanghai 2026-10-28) — Failed rows still have no reason

    Same inspection pass on prod tip ~55e1c27a (issue→合入 / PR→合入 via cookie proxy). Expanding the “Runs rows lack … failure reason” note already in this issue:

    Actual: Failed runs (examples seen: #1453, #1422, #1395) show no failure reason in the Runs list or the timeline — only a Failed badge / status. Operator cannot tell why it failed without digging elsewhere.

    Expected: When a run fails, surface a short reason (error / outcome / last node message) on the Runs row and on a timeline failure line.

    This issue’s expected already asks for “Runs rows show time + reason when Failed” and timeline failure + reason — keeping that here instead of a duplicate “no failure reason” issue. Sibling-header visibility remains the other half of this ticket.

    Not filing separately (dedupe). Owner: 「这些问题也要提issue去改」 (t640u).

  3. Birfy commented on Oct 28, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Triage

    agent-ready — reproduced against main at 176d33d034e741b68041c0676da1707001cb6e88 (2026-10-28), not only in the screenshot.

    Why a sibling failure never reaches the room. The client half of this shipped in #1494 (liveStageRuns accepts status === 'failed', the strip paints a Failed chip), but the host never sends a failed run, so that path is dead whenever another run is still live:

    • plugins/workflow/src/service.js:184 — runs: runningOf(lane), and runningOf keeps only live === true && status === 'running' (:203). A run that fails leaves lane.active and lives in lane.last and lane.history only.
    • Repro with the deliverable template: two concurrent runs (maxConcurrent: 2), then end one the way the stop / reap paths do (reset { runId } → endRun). Snapshot: runs = [#1445 running], activeCount = 1, run = #1445 — #1460 appears only as history: [{task, status: 'failed', at}], with no run id and no reason. The header has one strip, exactly as the screenshot.
    • plugins/workflow/client.js:551 — runHistoryRows hardcodes status: 'running' for every row it takes from runs, so a failed run routed through it would read "Running"; Runs (:725) renders neither at nor a reason, which is the second half of this issue.
    • The timeline gap is the silent ending: a step failure logs a line (narrate.js) and reset logs ■ 已停止, but the hand-off catch (service.js:555, endRun → releaseRun) and reap (:1062) / dispose (:1085) archive a run as failed with no log line at all — the 开始 then nothing shape of fix(workflow): every stage chat line is clipped at 240 characters with no way to read the rest (introduced by #1456) #1460.

    Scope going forward (one PR):

    1. service.js — a failed run that is still live and whose task differs from every running run's task stays in the workflow's runs, with what ended it (failure: { code, nodeName?, text?, at }); record that reason wherever a run becomes failed (step failure, stop, hand-off failure, reap/dispose); history rows carry the run id and that reason.
    2. client.js — the strip for a failed run names the reason instead of Waiting for a task; Runs rows show the run's own status (not a hardcoded "Running"), its time, and its reason.
    3. One tone: 'bad' timeline line for an ending that logs none today (hand-off failure, reap).
    4. Tests that fail on the current tree: a service test for the snapshot and the reason record, and a client test for the failed sibling strip plus the Runs row (status, time, reason).

    No blocking conflict. #1507 (a retry leaves duplicate rows for one task) stays open and undecided: this change surfaces a failed run only when its task differs from every running run's task, so a same-task retry still collapses to the running row and #1507 keeps its own question. #1494 merged; no open PR names #1493; no hold; unassigned.

  4. added
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 28, 2026
  5. Birfy commented on Oct 28, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Triage

    Claimed #1493 — branch fix/1493-failed-sibling-surface, pull request #1562 (Fixes #1493). First step was the reproduction above; the change keeps the failed sibling in workflow/state runs with a failure record, shows it on the strip and its Runs row with time and reason, and writes the timeline line the reap never wrote. Awaiting CI at the tip and a Reviewer PASS.

  6. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a templateagent-workingAn agent has claimed this issue (the claim comment names the branch)area:uiWeb/desktop UI and copybugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions