Skip to content

fix(workflow): Runs shows a failed last attempt twice (phantom Running + Failed) #1583

Closed

Description

@Birfy

Written-by: Triage

Split from #1507 — the pinned half of its triage comment (2026-10-28T02:22Z). #1507 keeps the shape decision (group retries vs mark superseded); this one does not depend on it and ships regardless.

What happens

With no run active and a failed last attempt, Runs shows that same attempt twice: a phantom Running row plus its own Failed history row.

plugins/workflow/client.js on main 0e6dfc0d:

  • liveStageRuns (:627-633) counts a run as live when run.live === true and its status is running or failed.
  • runHistoryRows (:645-658) paints every row from liveStageRuns as status: 'running' (:650-654), then appends every workflow.history row (:656). A failed-live attempt is therefore listed once as Running and once as Failed.

Expected

One row per attempt. With no active run and a failed last attempt: exactly one row, labelled Failed, zero Running rows. A genuine retry still shows two distinguishable attempts — the retry is the live/current one, the earlier one stays Failed.

Scope (display only)

plugins/workflow/client.js — runHistoryRows (and liveStageRuns if the fix needs the run's own status). No src/service.js change for this half: lane.history already carries at, and that plus task.id is enough to tell a live failed attempt from its history row. No new state, no new key.

Red first

plugins/workflow/test/client.test.js already covers runHistoryRows (:906, :922) but only with running live runs. Add the failed case:

const task = { id: '#1422', title: 'PR 1422' }
const workflow = {
  activeCount: 0,
  queue: [],
  runs: [{ id: 'run-a', live: true, status: 'failed', task }],
  run: { id: 'run-a', live: true, status: 'failed', task },
  history: [{ task, status: 'failed', at: '2026-10-28T02:00:00Z' }],
}
const rows = client.runHistoryRows(workflow)
assert.equal(rows.length, 1)
assert.equal(rows[0].status, 'failed')
assert.equal(rows.filter(row => row.status === 'running').length, 0)

Red on base 0e6dfc0d (today it returns two rows, one running).

Acceptance

  • The new case green; the existing runHistoryRows cases (:906, :922) and the runs tab shows one running row per concurrent live run (:934) stay green, so N concurrent live runs still render N rows.
  • UI check on a workflow whose last attempt failed: Runs shows one Failed row and no Running phantom; a real retry then shows two distinguishable attempts with the newest current.

Risk

Client-only display fix inside plugins/workflow; no secrets and no permission surface. The controller decides the tier.

Activity

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

    @Birfy
    CollaboratorAuthor

    Written-by: Triage

    agent-ready — split from #1507 so the pinned half can start without waiting on that issue's shape decision. The defect (a failed-live run painted running in runHistoryRows next to its own Failed history row), the red-first case, the files and the acceptance are in the body above; verified against plugins/workflow/client.js at main 0e6dfc0d.

  3. added
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 28, 2026
  4. self-assigned this
    on Oct 28, 2026
  5. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 28, 2026
  6. Birfy commented on Oct 28, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Claim d573

    Claimed — taking this to dev/1583-runs-dedup-failed-live (branched from main 0e6dfc0d).

    First step: the red-first failed-live case in plugins/workflow/test/client.test.js, then runHistoryRows in plugins/workflow/client.js paints one row per attempt and skips a history row that is already the live attempt.

    Scope stays the issue body: client-only display fix, no src/service.js change, no new state.

  7. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 28, 2026
  8. removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 28, 2026
  9. added a commit that references this issue on Oct 28, 2026
    ac7a916
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

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