{"record":{"id":"56da6759b5a35c18","repo":"windmill-labs/windmill","slug":"invalid-failure-module-only-rawscript-and-scri","errorCode":null,"errorMessage":"Invalid failure_module: only \"rawscript\" and \"script\" modules are supported","messagePattern":"Invalid failure_module: only \"rawscript\" and \"script\" modules are supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/chat/flow/editableFlowJson.ts","lineNumber":397,"sourceCode":"\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 {\n\t\tmodules,\n\t\tschema,\n\t\tpreprocessor_module: preprocessorModule,","sourceCodeStart":379,"sourceCodeEnd":415,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/chat/flow/editableFlowJson.ts#L379-L415","documentation":"validateEditableFlowJson in editableFlowJson.ts validates an AI-generated flow JSON before it is saved. A flow's special failure_module must be either a rawscript or a script module; any other module type (e.g. 'forloop', 'flow', 'http') is rejected because Windmill's failure handler only supports executing script code on failure. This is a pre-save guard so the invalid flow never reaches the backend.","triggerScenarios":"Calling validateEditableFlowJson (directly or via parsedFlow/revalidated/result/editable/patchedEditable) when the failure_module object has value.type set to something other than 'rawscript' or 'script', e.g. the LLM emitted a failure_module with type 'http' or 'loop'.","commonSituations":"LLM/copilot generating a failure module with the wrong module type; hand-editing flow JSON and copying a non-script module into failure_module; refactoring an existing module into the failure slot without changing its type.","solutions":["Change failure_module.value.type to 'rawscript' (inline code) or 'script' (path to an existing script)","Remove the failure_module if a failure handler is not needed","If the intent was arbitrary logic, wrap it as a rawscript module with the code in 'content'"],"exampleFix":"// before\nfailure_module: { id: 'failure', value: { type: 'http', ... } }\n// after\nfailure_module: { id: 'failure', value: { type: 'rawscript', language: 'python3', content: '...', ... } }","handlingStrategy":"validation","validationCode":"const ok = flow.failure_module == null || ['rawscript','script'].includes(flow.failure_module.value?.type)\nif (!ok) throw new Error('failure_module must be a rawscript or script module')","typeGuard":"function isValidFailureModule(m) {\n  return m != null && (m.value?.type === 'rawscript' || m.value?.type === 'script')\n}","tryCatchPattern":"try {\n  const editable = validateEditableFlowJson(json)\n  // save flow\n} catch (e) {\n  if (e.message.includes('Invalid failure_module')) {\n    // strip or fix failure_module and retry\n  } else throw e\n}","preventionTips":["Only ever emit 'rawscript' or 'script' as the failure_module type","Omit failure_module entirely when no failure handler is needed","Validate the flow JSON with validateEditableFlowJson before submitting it to the API"],"tags":["validation","flow","schema"],"backgroundTag":"schema-validation-failed","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"}