windmill-labs/windmill · error
Invalid preprocessor_module: id must be "${SPECIAL_MODULE_ID
Error message
Invalid preprocessor_module: id must be "${SPECIAL_MODULE_IDS.PREPROCESSOR}" What it means
If a preprocessor_module is supplied, its `id` must be the reserved SPECIAL_MODULE_IDS.PREPROCESSOR value; the preprocessor is a distinguished module identified by that fixed id, not an arbitrary one. A differently-id'd module would not be recognized as the preprocessor by the backend, so the validator rejects it at edit time.
Source
Thrown at frontend/src/lib/components/copilot/chat/flow/editableFlowJson.ts:379
const path = issue?.path?.join('.') ?? 'settings'
throw new Error(`Invalid flow setting ${path}: ${issue?.message ?? 'unknown error'}`)
}
const settings = pickFlowValueSettings(settingsResult.data)
const modules = validateFlowModules(flow.modules, ctx)
const schema = validateFlowSchema(flow.schema)
const preprocessorModule = validateOptionalFlowModule(
flow.preprocessor_module,
'preprocessor_module'
)
const failureModule = validateOptionalFlowModule(flow.failure_module, 'failure_module')
const groupModuleIds = new Set(collectAllFlowModuleIdsFromModules(modules))
const groups = validateFlowGroups(flow.groups, groupModuleIds)
const notes = validateFlowNotes(flow.notes, groupModuleIds)
if (preprocessorModule) {
if (preprocessorModule.id !== SPECIAL_MODULE_IDS.PREPROCESSOR) {
throw new Error(
`Invalid preprocessor_module: id must be "${SPECIAL_MODULE_IDS.PREPROCESSOR}"`
)
}
if (
preprocessorModule.value.type !== 'rawscript' &&
preprocessorModule.value.type !== 'script'
) {
throw new Error(
'Invalid preprocessor_module: only "rawscript" and "script" modules are supported'
)
}
}
if (failureModule) {
if (failureModule.id !== SPECIAL_MODULE_IDS.FAILURE) {
throw new Error(`Invalid failure_module: id must be "${SPECIAL_MODULE_IDS.FAILURE}"`)
}
if (failureModule.value.type !== 'rawscript' && failureModule.value.type !== 'script') {
throw new Error('Invalid failure_module: only "rawscript" and "script" modules are supported')View on GitHub (pinned to e474e8803c)
Solutions
- Set preprocessor_module.id to the exact required constant shown in the error message (SPECIAL_MODULE_IDS.PREPROCESSOR).
- Re-run the tool after fixing the id.
- Never reuse a regular module's id for the preprocessor.
Example fix
// before
{"preprocessor_module":{"id":"prep",...}}
// after
{"preprocessor_module":{"id":"preprocessor",...}} Defensive patterns
Strategy: validation
Validate before calling
import { SPECIAL_MODULE_IDS } from '../shared'
if (flow.preprocessor_module && flow.preprocessor_module.id !== SPECIAL_MODULE_IDS.PREPROCESSOR)
throw new Error(`preprocessor_module.id must be ${SPECIAL_MODULE_IDS.PREPROCESSOR}`) Try / catch
try {
validateEditableFlowJson(raw)
} catch (e) {
if (String(e.message).startsWith('Invalid preprocessor_module: id')) {
raw.preprocessor_module.id = SPECIAL_MODULE_IDS.PREPROCESSOR
return validateEditableFlowJson(raw)
}
throw e
} Prevention
- Copy SPECIAL_MODULE_IDS.PREPROCESSOR into generated preprocessor modules
- Never assign fresh UUIDs to special modules
- Preserve the special id when moving a module into preprocessor_module
When it happens
Trigger: Calling flowTools modules/patches with preprocessor_module whose id is e.g. "prep", "preprocessor_1", or a copied regular module id instead of the required SPECIAL_MODULE_IDS.PREPROCESSOR constant.
Common situations: An LLM invents an id for the preprocessor; a regular script module is moved into preprocessor_module without re-id'ing it; a template is edited and the id renamed.
Related errors
- Invalid failure_module: id must be "${SPECIAL_MODULE_IDS.FAI
- Invalid ${fieldName}: ${error?.message ?? 'unknown error'}
- Invalid preprocessor_module: only "rawscript" and "script" m
- result.substring(__RESULT_ERR_PREFIX.length)
- Invalid migration name '${name}': use only letters, digits,
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/63a4d05501cf61ae.
Report an issue: GitHub.