windmill-labs/windmill · error · Error
Invalid group at index ${index}: start_id "${g.start_id}" do
Error message
Invalid group at index ${index}: start_id "${g.start_id}" does not match any flow module What it means
validateFlowGroups validates the `groups` array an AI agent passes to patch_flow_json/set_flow_json. Each group's start_id and end_id must reference an existing flow module; when a moduleIds set is supplied and start_id is not found in it, this error is thrown. It exists to prevent groups that visually dangle on the canvas because they point at modules that don't exist.
Source
Thrown at frontend/src/lib/components/copilot/chat/flow/helperUtils.ts:121
}
if (typeof g.end_id !== 'string' || !g.end_id) {
throw new Error(`Invalid group at index ${index}: end_id must be a non-empty string`)
}
if (moduleIds) {
if (!moduleIds.has(g.start_id)) {
throw new Error(
`Invalid group at index ${index}: start_id "${g.start_id}" does not match any flow module`
)
}
if (!moduleIds.has(g.end_id)) {
throw new Error(
`Invalid group at index ${index}: end_id "${g.end_id}" does not match any flow module`
)
}
}
if (g.color !== undefined && g.color !== null) {
if (typeof g.color !== 'string' || !ALLOWED_NOTE_COLORS.has(g.color)) {
throw new Error(
`Invalid group at index ${index}: color must be one of ${[...ALLOWED_NOTE_COLORS].join(', ')}`
)
}
}
return g as unknown as FlowGroup
})
}
/**
* Validate the optional array of sticky notes the agent attached to the flow.
* Notes are editor-only annotations and do not affect execution.
*
* `free` notes are the supported kind (standalone canvas annotations). The
* `group` note type is deprecated for creation — the chat prompt steers the
* agent toward `groups` instead — but it is still ACCEPTED here so flows that
* already contain group notes round-trip cleanly through `patch_flow_json` /
* `set_flow_json` rather than being rejected. When `moduleIds` is provided,
* every `contained_node_ids` entry of a `group` note must reference an existingView on GitHub (pinned to e474e8803c)
Solutions
- Copy module ids verbatim from the flow value the tools returned (each module's `id` field), never invent them
- Re-fetch the current flow JSON to see which module ids actually exist before setting groups
- If the module was intended to be new, add the module itself in the same update and use its generated id
- Drop or fix the offending group entry at the reported index
Example fix
// before
groups: [{ start_id: 'step_1', end_id: 'step_2' }]
// after — use real ids from flow.value.modules
groups: [{ start_id: flow.value.modules[0].id, end_id: flow.value.modules[1].id }] Defensive patterns
Strategy: validation
Validate before calling
const moduleIds = new Set<string>(); forEachFlowModule(flow.value, (m) => { moduleIds.add(m.id); });
for (const [i, g] of (groups ?? []).entries()) {
if (!moduleIds.has(g.start_id)) throw new Error(`groups[${i}].start_id "${g.start_id}" is not a flow module id`);
} Type guard
function isValidGroupId(id: unknown, moduleIds: Set<string>): id is string {
return typeof id === 'string' && moduleIds.has(id);
} Try / catch
try {
const validated = validateFlowGroups(rawGroups, moduleIds);
} catch (e) {
if (e instanceof Error && e.message.includes('does not match any flow module')) {
// surface index + offending id back to the agent so it can re-read the flow
} else throw e;
} Prevention
- Always build groups from the module ids present in the latest flow value you received from the tool
- Copy ids verbatim; never abbreviate or re-generate them
- If you added modules in the same update, use the exact ids you assigned them
When it happens
Trigger: Calling updateFlowJson/patch_flow_json with groups: [{start_id: 'mod_x', end_id: 'mod_y'}] where 'mod_x' is not a module id in the current flow (typo, hallucinated id by the LLM, or a module deleted earlier in the same edit).
Common situations: An LLM agent invents plausible-looking module ids instead of copying them from the flow it was given; the agent references a module from a previous flow revision that was renamed or removed; the caller forgets to include newly-added module ids in the moduleIds set.
Related errors
- Invalid group at index ${index}: end_id "${g.end_id}" does n
- Flow groups must be an array
- Invalid group at index ${index}: must be an object
- Invalid group at index ${index}: start_id must be a non-empt
- Invalid group at index ${index}: end_id must be a non-empty
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/d38f6dd33f2e3599.
Report an issue: GitHub.