windmill-labs/windmill · error
Duplicated node detected: ${module.id}
Error message
Duplicated node detected: ${module.id} What it means
graphBuilder's addNode refuses to insert two graph nodes with the same id, since React Flow requires unique node ids. A duplicate means the same FlowModule (same id) was encountered twice while walking the flow's modules.
Source
Thrown at frontend/src/lib/components/graph/graphBuilder.svelte.ts:466
try {
if (!modules) {
return { nodes: {}, edges: [] }
}
const nodes: NodeLayout[] = []
const edges: Edge[] = []
// Lookup map from module ID to the original reactive FlowModule objects.
const moduleMap = new Map<string, FlowModule>()
for (const m of getAllModules(modules, failureModule)) {
moduleMap.set(m.id, m)
}
function addNode(module: FlowModule, extraData?: Record<string, any>) {
const duplicated = nodes.find((n) => n.id === module.id)
if (duplicated) {
console.log('Duplicated node detected: ', module, duplicated)
throw new Error(`Duplicated node detected: ${module.id}`)
}
nodes.push({
id: module.id,
data: {
module: module,
id: module.id,
parentIds: [],
eventHandlers: eventHandlers,
testModuleState: extra.testModuleStates?.states?.[module.id],
insertable: extra.insertable && !module.id.startsWith('subflow:'),
editMode: extra.editMode,
isOwner: extra.isOwner,
assets: getFlowModuleAssets(module, extra.additionalAssetsMap),
moduleAction: extra.moduleActions?.[module.id],
...extraData
},
type: 'module',View on GitHub (pinned to e474e8803c)
Solutions
- Open the flow JSON and give each duplicated step a unique id, then redeploy.
- In the editor, delete and re-add the duplicated step so it gets a fresh id.
- If the flow was generated by a script, fix the generator to assign unique ids per step.
- Check for accidental double-inclusion of child modules (branch/foreach inputs) and deduplicate.
Example fix
// before
[{ "id": "step1", ... }, { "id": "step1", ... }]
// after
[{ "id": "step1", ... }, { "id": "step2", ... }] Defensive patterns
Strategy: validation
Validate before calling
const seen = new Set()
for (const m of modules) { if (seen.has(m.id)) console.warn('duplicate module id', m.id); seen.add(m.id) } Type guard
function hasUniqueIds(modules) { return new Set(modules.map(m => m.id)).size === modules.length } Try / catch
try { buildGraph(flow) } catch (e) { if (String(e.message).startsWith('Duplicated node detected')) reloadFlowWithFreshIds(); else throw e } Prevention
- Regenerate ids when copying/duplicating steps or branches
- Validate flow JSON uniqueness before deploying generated flows
- Never hand-edit step ids without checking global uniqueness
When it happens
Trigger: processModules (or addFailureNode) encounters two FlowModule entries with identical module.id — e.g. the flow JSON literally lists the same step id twice, or a branch/foreach expansion re-emits a step already added.
Common situations: Hand-edited or programmatically generated flow JSON reusing a step id; copy-paste of a branch in the editor that duplicated ids; a backend/plugin bug emitting a module in both the main list and a child list.
Related errors
- This forked workspace '${workspaceId}' (${workspaceName}) al
- Duplicate module ID found in preprocessor_module: ${preproce
- Duplicate module ID found in failure_module: ${failureModule
- Duplicate group id: '${g.id}'
- Group '${g.id}' has inverted range: start_id='${g.start_id}'
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/acd29ba2a3bf15ca.
Report an issue: GitHub.