windmill-labs/windmill · error · Error
Invalid group at index ${index}: color must be one of ${[...
Error message
Invalid group at index ${index}: color must be one of ${[...ALLOWED_NOTE_COLORS].join(', ')} What it means
validateFlowGroups restricts group colors to the NoteColor palette (yellow, blue, green, purple, pink, orange, red, cyan, lime, gray) because the renderer keys its styles by these exact names; arbitrary strings like hex codes would render unstyled or break the color picker. A non-string color, or a string outside the palette, throws this error.
Source
Thrown at frontend/src/lib/components/copilot/chat/flow/helperUtils.ts:128
`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 existing
* module.
*
* A provided palette `color` is always preserved as-is; the default is only
* filled in when a note omits `color` entirely (FlowNote.color is required).
*
* Free notes are also given a concrete `position` and `size` when missing. A
* free note without geometry is not draggable/resizable in the editor (you'dView on GitHub (pinned to e474e8803c)
Solutions
- Use one of the palette names exactly: yellow, blue, green, purple, pink, orange, red, cyan, lime, gray
- Omit the color field entirely (undefined/null is accepted) to get the default color
- Map any hex/CSS value to the nearest palette name before sending
Example fix
// before
groups: [{ start_id: 'a', end_id: 'b', color: '#3498db' }]
// after
groups: [{ start_id: 'a', end_id: 'b', color: 'blue' }] Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED = ['yellow','blue','green','purple','pink','orange','red','cyan','lime','gray'];
for (const [i, g] of (groups ?? []).entries()) {
if (g.color != null && !ALLOWED.includes(g.color)) throw new Error(`groups[${i}].color "${g.color}" not in palette`);
} Type guard
function isNoteColor(c: unknown): c is NoteColor {
return typeof c === 'string' && (Object.values(NoteColor) as string[]).includes(c);
} Try / catch
try {
validateFlowGroups(rawGroups, moduleIds);
} catch (e) {
if (e instanceof Error && e.message.includes('color must be one of')) {
// retry with color omitted to accept the default
} else throw e;
} Prevention
- Only use the ten documented palette names, lowercase
- Omit color rather than guessing a hex value
- Keep a shared constant list of allowed colors in tool-call-building code
When it happens
Trigger: groups: [{ start_id, end_id, color: '#ff0000' }] or color: 'azure' or color: 3 passed to patch_flow_json/set_flow_json.
Common situations: An LLM agent outputs hex/CSS color values instead of palette names; a caller passes a numeric enum index instead of the string name; copy-pasted group config from another tool uses different color vocabulary.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid note at index ${index}: color must be one of ${[...A
- 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/9a975611b7a04932.
Report an issue: GitHub.