windmill-labs/windmill · error
'value.modules' must be a list
Error message
'value.modules' must be a list
What it means
validateShape in FlowYamlEditor.svelte checks that the parsed OpenFlow document's 'value.modules' key is an array, since a Windmill flow body is a list of modules. It throws when 'value.modules' is absent, a scalar, or a non-array object — meaning the flow body shape is wrong even though the document has a proper 'value' mapping.
Source
Thrown at frontend/src/lib/components/flows/header/FlowYamlEditor.svelte:47
code = YAML.stringify(filteredContentForExport(flowStore.val))
initialCode = code
editor?.setCode(code)
}
/** `value` is assigned unconditionally below and `FlowEditor` dereferences
* `flowStore.val.value.modules`, so an OpenFlow document missing it takes the
* whole editor down mid-render — after the toast has already claimed success.
* Reject it up front instead. */
function validateShape(parsed: unknown) {
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
throw new Error('the document must be a mapping (key: value)')
}
const value = (parsed as Record<string, unknown>).value
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
throw new Error("missing 'value' - paste a whole OpenFlow document, not just its value")
}
if (!Array.isArray((value as Record<string, unknown>).modules)) {
throw new Error("'value.modules' must be a list")
}
}
function validateGroups(groups: { start_id: string; end_id: string }[] | undefined) {
if (!groups) return
const seen = new Set<string>()
for (const g of groups) {
const key = `${g.start_id}:${g.end_id}`
if (seen.has(key)) {
throw new Error(`Duplicate group: '${g.start_id}' → '${g.end_id}'`)
}
seen.add(key)
}
}
function apply() {
try {
const parsed = YAML.parse(code)View on GitHub (pinned to e474e8803c)
Solutions
- Ensure 'value.modules' exists and is a YAML list, with each module prefixed by '- id: ...'
- If you intended a single step, wrap it in a one-element list
- Check the key spelling is exactly 'modules' and it is nested directly under 'value'
- Validate against an exported flow's YAML to confirm the expected structure
Example fix
// before (modules as single object)
value:
modules:
id: a
value:
type: rawscript
// after (modules as a list)
value:
modules:
- id: a
value:
type: rawscript Defensive patterns
Strategy: validation
Validate before calling
const parsed = yaml.load(text)
if (!Array.isArray(parsed?.value?.modules)) {
alert('value.modules must be a YAML list of module objects')
} Type guard
function hasModulesList(v: unknown): v is { value: { modules: unknown[] } } {
return typeof v === 'object' && v !== null && Array.isArray((v as any).value?.modules)
} Try / catch
try {
editor.apply(yamlText)
} catch (e) {
if (e.message.includes("'value.modules' must be a list")) {
sendUserToast('Each module must be a list item: prefix with "- "', true)
}
} Prevention
- Prefix every module with '-' so it parses as a list item
- Use the exact key 'modules' nested under 'value'
- Compare with an exported flow's YAML when in doubt
- Round-trip edit: apply → re-download → edit → re-apply
When it happens
Trigger: Calling apply() → validateShape() with YAML where value.modules is missing, set to a single module object instead of a list, misspelled (e.g. 'value.Modules' or 'value.steps'), or a mapping of module-id → module.
Common situations: Editing YAML by hand and dropping the list syntax (a dash) so modules becomes a single object; porting from another flow format that uses a different key name for steps; accidentally deleting the modules list during a merge.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- missing 'value' - paste a whole OpenFlow document, not just
- Document must be a string
- Unsupported trigger kind: ${target.triggerKind}
- the document must be a mapping (key: value)
- Duplicate group: '${g.start_id}' → '${g.end_id}'
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/c51b456b9f07a522.
Report an issue: GitHub.