{"record":{"id":"8c380a73f500e7ef","repo":"windmill-labs/windmill","slug":"invalid-failure-module-id-must-be-special-modu","errorCode":null,"errorMessage":"Invalid failure_module: id must be \"${SPECIAL_MODULE_IDS.FAILURE}\"","messagePattern":"Invalid failure_module: id must be \"(.+?)\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/chat/flow/editableFlowJson.ts","lineNumber":394,"sourceCode":"\n\tif (preprocessorModule) {\n\t\tif (preprocessorModule.id !== SPECIAL_MODULE_IDS.PREPROCESSOR) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid preprocessor_module: id must be \"${SPECIAL_MODULE_IDS.PREPROCESSOR}\"`\n\t\t\t)\n\t\t}\n\t\tif (\n\t\t\tpreprocessorModule.value.type !== 'rawscript' &&\n\t\t\tpreprocessorModule.value.type !== 'script'\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t'Invalid preprocessor_module: only \"rawscript\" and \"script\" modules are supported'\n\t\t\t)\n\t\t}\n\t}\n\tif (failureModule) {\n\t\tif (failureModule.id !== SPECIAL_MODULE_IDS.FAILURE) {\n\t\t\tthrow new Error(`Invalid failure_module: id must be \"${SPECIAL_MODULE_IDS.FAILURE}\"`)\n\t\t}\n\t\tif (failureModule.value.type !== 'rawscript' && failureModule.value.type !== 'script') {\n\t\t\tthrow new Error('Invalid failure_module: only \"rawscript\" and \"script\" modules are supported')\n\t\t}\n\t}\n\n\tconst ids = new Set(collectAllFlowModuleIdsFromModules(modules))\n\tif (preprocessorModule) {\n\t\tif (ids.has(preprocessorModule.id)) {\n\t\t\tthrow new Error(`Duplicate module ID found in preprocessor_module: ${preprocessorModule.id}`)\n\t\t}\n\t\tids.add(preprocessorModule.id)\n\t}\n\tif (failureModule && ids.has(failureModule.id)) {\n\t\tthrow new Error(`Duplicate module ID found in failure_module: ${failureModule.id}`)\n\t}\n\n\treturn {","sourceCodeStart":376,"sourceCodeEnd":412,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/chat/flow/editableFlowJson.ts#L376-L412","documentation":"If a failure_module is supplied, its `id` must be the reserved SPECIAL_MODULE_IDS.FAILURE value; the failure handler is a distinguished module identified by that fixed id. Any other id would not be recognized as the failure handler by the backend, so it is rejected at edit time.","triggerScenarios":"Calling flowTools modules/patches with failure_module whose id is e.g. \"failure_handler\", \"on_failure\", or a copied regular module id instead of SPECIAL_MODULE_IDS.FAILURE.","commonSituations":"An LLM invents a descriptive id for the failure module; a regular error-handling script is moved into failure_module without re-id'ing it; renaming during a template edit.","solutions":["Set failure_module.id to the exact required constant shown in the error message (SPECIAL_MODULE_IDS.FAILURE).","Ensure failure_module.value.type is \"rawscript\" or \"script\" (a sibling check throws otherwise).","Re-run the tool after fixing the id."],"exampleFix":"// before\n{\"failure_module\":{\"id\":\"on_failure\",...}}\n// after\n{\"failure_module\":{\"id\":\"failure\",...}}","handlingStrategy":"validation","validationCode":"import { SPECIAL_MODULE_IDS } from '../shared'\nif (flow.failure_module && flow.failure_module.id !== SPECIAL_MODULE_IDS.FAILURE)\n  throw new Error(`failure_module.id must be ${SPECIAL_MODULE_IDS.FAILURE}`)","typeGuard":null,"tryCatchPattern":"try {\n  validateEditableFlowJson(raw)\n} catch (e) {\n  if (String(e.message).startsWith('Invalid failure_module: id')) {\n    raw.failure_module.id = SPECIAL_MODULE_IDS.FAILURE\n    return validateEditableFlowJson(raw)\n  }\n  throw e\n}","preventionTips":["Copy SPECIAL_MODULE_IDS.FAILURE into generated failure modules","Never assign fresh UUIDs to special modules","Preserve the special id when moving a module into failure_module"],"tags":["validation","flow-module","reserved-id"],"backgroundTag":"invalid-identifier-name","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}