Skip to content

workflow: Parallel mode in the New workflow dialog gives the third "Add a Bot" a duplicate node id, so Create is refused #2663

Closed

Description

@Birfy

Written-by: Chief

What happens

The New workflow dialog allocates a node id from the layer count, not from the nodes added so far: plugins/workflow/client.js:1600-1611

const add = () => {
  const bot = locals.find(item => item.id === botId)
  if (!bot) return
  setSteps(list => {
    const node = { id: `n${list.length + 1}`, botId: bot.id, name: bot.name, role: bot.role ?? '' }
    if (parallel && list.length > 0) {
      const next = list.slice()
      next[next.length - 1] = [...next[next.length - 1], node]
      return next
    }
    return [...list, [node]]
  })
}

With Parallel checked, a new node joins the last layer and the number of layers stays at 1, so every node after the first two gets n2:

layers = [["n1","n2","n2"]]
nodes  = [{"id":"n1","name":"A"},{"id":"n2","name":"B"},{"id":"n2","name":"C"}]
ids    = n1,n2,n2 | unique = 2

Node ids are the graph's unique key: plugins/workflow/src/graph.js:263 refuses the whole create with Node n2 is listed twice (core/src/shared/workflow.js:528 carries the same rule for node/duplicate-id). So the user adds three Bots in Parallel, presses Create, and nothing is created — the error names the node id, not the dialog.

Reproduction

/data/dsh/bot/workspace/tmp/idau1108/repro/dupnode.mjs replays the dialog's own allocation loop, then feeds the result to the real workflow/create action on tip d8a896c4a70a9aab9e7c5d46f004f70c5c31211f:

$ node dupnode.mjs
layers = [["n1","n2","n2"]]
nodes  = [{"id":"n1","name":"A"},{"id":"n2","name":"B"},{"id":"n2","name":"C"}]
ids    = n1,n2,n2 | unique = 2
$ node run.mjs
workflow/create -> {"ok":false,"error":"Node n2 is listed twice"}
workflow stored: false

Reachable from

Sidebar → Workflows → New → tick Parallel → Add a Bot three times → Create. Two nodes in Parallel is fine (n1, n2); the third is the first duplicate. The same n${length + 1} allocation is the dialog's only path, so any Parallel workflow with three or more Bots in one layer cannot be created from the UI at all.

Fix

The file already has a collision-aware allocator for the canvas path, nextNodeId(nodes) at client.js:683-688, which takes the flat node list and skips ids already in use. Use it here:

const node = { id: nextNodeId(list.flat()), botId: bot.id, name: bot.name, role: bot.role ?? '' }

Test to add (red first)

plugins/workflow/test/client.test.js already drives this dialog. Add a case that opens New workflow, ticks Parallel, adds three Bots from the roster, and asserts the three node ids are distinct and that Create is called with a graph the service accepts (graph.js unique-id check passes). On the current tip it fails with n1,n2,n2; after the fix it passes. Keep an assertion that sequential (Parallel unticked) adding still yields n1,n2,n3.

Scope

  • plugins/workflow/client.js (CreateModal.add, lines 1600-1611) and plugins/workflow/test/client.test.js
  • changelog.d/<this-issue>-<slug>.fixed.md

Not in scope: nextNodeId itself, the canvas drop path (client.js:1232, already correct), graph.js validation.

Activity

  1. self-assigned this
    on Nov 8, 2026
  2. added
    bugSomething isn't working
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    area:automationScheduled tasks and automation
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Nov 8, 2026
  3. Birfy commented on Nov 8, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Chief

    已派实现线(flybot/workflow/assign,workflow wf-67229151,task i2663-impl)。这条 agent-working 只是让下一拍节拍不要重复派活,分支名与红先证据以 build/ship 节点的交付为准。

  4. removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Nov 8, 2026
  5. added 2 commits that reference this issue on Nov 9, 2026
    d02f292
    af9a30b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:automationScheduled tasks and automationbugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions