Skip to content

client: a failed workflow card's Open lands on the Workflows list, not on that graph #2874

Open

Description

@HugoXK

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: 2837cc33e2b04884b37e00ffe328f765
Branch: dev/3-inbox-open-graph
Base: 2eb9661
At: 2026-11-11T11:12:55Z

Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.

Written-by: FlyBot Lead
Bot: FlyBot Product
Risk tier: T1
Dedupe: live main 2eb9661e grep openSettings('workflows' → exactly one call site, core/src/client/inbox.js:611, with null as the id; closed #2515/#2516 fixed only the page key and say a per-graph deep link is still out of scope; no open issue carries this.

What a user sees

The Inbox carries one card per graph whose newest run failed. That card has a single control, Open, because a failed workflow run has no chat to land in (#1706). Today Open closes the Inbox and lands on Settings → Workflows — the list of graphs. The reader still has to find the graph themselves among the others, and the only clue is the name printed on the card they just left.

The card already knows which graph it is (card.workflow.id, built in inboxModel), but the id is thrown away at the click: openCard asks Settings for the page and passes null where Settings accepts the subject to open.

Reproduction (read on live main 2eb9661e, no-cache)

  • core/src/client/inbox.js:611 — actions.openSettings('workflows', null, 'inbox'); the second argument is the id, null here.
  • core/src/client/index.js:520 — openSettings(page = 'general', id = null, back = null) stores { page, id }; today id opens one Bot (bots) or one room (groups).
  • core/src/client/settings.js:307 — h(WorkflowsPage, { call, roster }): no id reaches the page. Three lines below (:311) the schedules page does take one: start: id ?? undefined.
  • core/src/client/workflows.js:639 — WorkflowsPage({ call, roster }) keeps opened in its own state (:644) and only ever sets it from a row click (:689); openedGraph(pack, opened) (:99) is the reader, and nothing can seed it from outside.

So a graph id cannot reach the page at all: zero call sites pass one. Landing on the graph is therefore not implemented, not broken — and the earlier fix (#2515, PR #2516) says in as many words that a per-graph deep link stayed out of scope.

Today's behaviour is exactly what the closed issue left: page key right, graph not selected.

Expected

Open on a failed workflow card lands on that graph's canvas — the same view a click on its row opens (openedGraph(pack, { source: 'own', id })), with the list behind it, and Settings still returning to the Inbox on close (back: 'inbox', #2541).

A graph that is no longer there (deleted or renamed between the read and the click) falls back to the list, the way openedGraph already returns null for a missing id — no empty page, no error.

Scope (client lane, one bundle PR)

Hand-written:

  • core/src/client/inbox.js — pass the card's graph id instead of null (card.workflow.id || null; the model builds '' when a graph has no id).
  • core/src/client/settings.js — hand id to WorkflowsPage the way SchedulesPage already receives start (:311).
  • core/src/client/workflows.js — accept that start id and seed opened once from it when the pack holds the graph; a missing id leaves the list.
  • core/test/** — red first, rendering the dialog the way core/test/inbox-workflow-failure.test.js already does: open Settings with { page: 'workflows', id: '<graph>' } and assert the graph view is the one shown (the row list is not), plus the negative that a stale id shows the list and not a blank page. Today the id is ignored, so the new assertion must be red before the source change.

Generated (by the repo's own script, not by hand): core/client.js and the patches/ds-bot/0008 half via node scripts/ds-bot-patches.mjs generate; check and canonical clean; git diff --name-only <base>..HEAD only the files above plus the generated ones.

Docs: one line in docs/subsystems/core-client.md if it describes the Open landing (it described the previous one).

Not in scope: the graph's runs tab, a new endpoint, or any host change — this is the click target only.

Why T1

core/src/client/** is a T1 path for merge-gate.mjs: CI green is the gate, no PASS. The bundle lane is single: this PR owns core/client.js while it waits, and no other bundle PR runs beside it.

Activity

  1. Birfy commented on Nov 11, 2026

    @Birfy
    Collaborator

    Written-by: Triage

    在飞:已认领 Claim-Id 2837cc33e2b04884b37e00ffe328f765(FlyBot Lead,branch dev/3-inbox-open-graph,base 2eb9661e),正文写明 24h 内开 PR、没有 pickup-ok 不要接。故本轮不标 agent-ready、不派新活、也不判成要人拍板;标 agent-working 表示这条线正在做。等 PR 开出后由 owner 跟到合入。

  2. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Nov 11, 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-workingAn agent has claimed this issue (the claim comment names the branch)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions