windmill-labs/windmill · error

Invalid failure_module: only "rawscript" and "script" module

Error message

Invalid failure_module: only "rawscript" and "script" modules are supported

What it means

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.

Source

Thrown at frontend/src/lib/components/copilot/chat/flow/editableFlowJson.ts:397

			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')
		}
	}

	const ids = new Set(collectAllFlowModuleIdsFromModules(modules))
	if (preprocessorModule) {
		if (ids.has(preprocessorModule.id)) {
			throw new Error(`Duplicate module ID found in preprocessor_module: ${preprocessorModule.id}`)
		}
		ids.add(preprocessorModule.id)
	}
	if (failureModule && ids.has(failureModule.id)) {
		throw new Error(`Duplicate module ID found in failure_module: ${failureModule.id}`)
	}

	return {
		modules,
		schema,
		preprocessor_module: preprocessorModule,

View on GitHub (pinned to e474e8803c)

Solutions

  1. Change failure_module.value.type to 'rawscript' (inline code) or 'script' (path to an existing script)
  2. Remove the failure_module if a failure handler is not needed
  3. If the intent was arbitrary logic, wrap it as a rawscript module with the code in 'content'

Example fix

// before
failure_module: { id: 'failure', value: { type: 'http', ... } }
// after
failure_module: { id: 'failure', value: { type: 'rawscript', language: 'python3', content: '...', ... } }
Defensive patterns

Strategy: validation

Validate before calling

const ok = flow.failure_module == null || ['rawscript','script'].includes(flow.failure_module.value?.type)
if (!ok) throw new Error('failure_module must be a rawscript or script module')

Type guard

function isValidFailureModule(m) {
  return m != null && (m.value?.type === 'rawscript' || m.value?.type === 'script')
}

Try / catch

try {
  const editable = validateEditableFlowJson(json)
  // save flow
} catch (e) {
  if (e.message.includes('Invalid failure_module')) {
    // strip or fix failure_module and retry
  } else throw e
}

Prevention

When it happens

Trigger: 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'.

Common situations: 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.

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


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/56da6759b5a35c18. Report an issue: GitHub.