windmill-labs/windmill · error
Invalid flow modules:\n${errors.join('\n')}
Error message
Invalid flow modules:\n${errors.join('\n')} What it means
After Array.isArray passes, validateFlowModules runs the modules through the Zod flowModulesSchema. On failure it formats up to 5 issues — attributing each to its module ID and field path where possible — and throws this aggregated error. It is the canonical 'your modules payload doesn't match the flow module schema' message.
Source
Thrown at frontend/src/lib/components/copilot/chat/flow/editableFlowJson.ts:251
modulesSchema,
path as (string | number)[],
parsedModules
)
if (targetSchema) {
const expectedFormat = getExpectedFormat(targetSchema)
if (expectedFormat) {
message += `\n Expected format: ${expectedFormat}`
}
}
}
if (moduleId) {
return `Module "${moduleId}" -> ${fieldPath}: ${message}`
}
return `${path.join('.')}: ${message}`
})
throw new Error(`Invalid flow modules:\n${errors.join('\n')}`)
}
const ids = collectAllFlowModuleIdsFromModules(parsedModules)
if (ids.length !== new Set(ids).size) {
throw new Error('Duplicate module IDs found in flow')
}
const reservedIds = ids.filter(
(id) => id === SPECIAL_MODULE_IDS.PREPROCESSOR || id === SPECIAL_MODULE_IDS.FAILURE
)
if (reservedIds.length > 0) {
throw new Error(
'Special modules must be provided via preprocessor_module and failure_module, not inside modules'
)
}
// Not expressible in the schema: `provider` is required only when the step is standalone, and
// making AiAgent a conditional union breaks the FlowModuleValue discriminated union it belongs to.View on GitHub (pinned to e474e8803c)
Solutions
- Read the per-module messages in the error (Module "<id>" -> <field>: <reason>) and fix exactly those fields.
- Ensure every module has a unique 'id' and a 'value' whose 'type' matches the schema union (rawscript, script, flow, branch, etc.).
- Supply all required fields for the chosen type — e.g. rawscript needs content, language, and tags/input_transforms in the right shapes.
- Model the payload on the current editable flow JSON output, which is guaranteed schema-conformant.
Example fix
// before: rawscript missing content
{ id: 'm1', value: { type: 'rawscript', language: 'python3' } }
// after
{ id: 'm1', value: { type: 'rawscript', language: 'python3', content: 'print(1)' } } Defensive patterns
Strategy: validation
Validate before calling
import { flowModulesSchema } from './editableFlowJson'
const res = flowModulesSchema.safeParse(modules)
if (!res.success) console.error(res.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`)) Type guard
function modulesMatchSchema(v: unknown): v is FlowModule[] {
return flowModulesSchema.safeParse(v).success
} Try / catch
try {
await setFlow({ modules })
} catch (e) {
if (e.message.startsWith('Invalid flow modules:')) {
// error lists each bad module as Module "<id>" -> <field>: <reason>
fixListedFields(e.message)
} else throw e
} Prevention
- Fix exactly the fields named in the error (module id -> field path)
- Match each module's value.type to the schema union and supply its required fields
- Copy module shapes from a known-good editable flow JSON
- Run the Zod schema client-side before submitting
When it happens
Trigger: validateFlowModules receiving an array whose entries violate flowModulesSchema: missing id, unknown/invalid value.type discriminator, missing required fields for the module type (e.g. rawscript without content/language), wrong input_transform shape, or invalid nested fields.
Common situations: The AI invents a module type not in the discriminated union; a required field like 'value.content' or 'value.language' is omitted for rawscript; transforms use the wrong key (expression vs value); a field intended for one module kind is put on another.
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
- Flow modules must be an array
- Invalid ${field}:\n${errors.join('\n')}
- Duplicate module IDs found in flow
- Special modules must be provided via preprocessor_module and
- Invalid ${fieldName}: ${error?.message ?? 'unknown error'}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/6a8cec574e89430b.
Report an issue: GitHub.