windmill-labs/windmill · error

Invalid ${field}: only "rawscript" and "script" modules are

Error message

Invalid ${field}: only "rawscript" and "script" modules are supported

What it means

validateSpecialFlowModule finally checks parsedModule.value.type and permits only 'rawscript' or 'script'; anything else throws 'Invalid <field>: only "rawscript" and "script" modules are supported'. Special flow slots must be backed by executable script modules.

Source

Thrown at frontend/src/lib/components/copilot/chat/flow/core.ts:278

	}

	const result = flowModuleSchema.safeParse(module)
	if (!result.success) {
		const errors = result.error.issues.slice(0, 5).map((issue) => {
			const path = issue.path.length > 0 ? issue.path.join('.') : field
			return `${path}: ${issue.message}`
		})
		throw new Error(`Invalid ${field}:\n${errors.join('\n')}`)
	}

	const parsedModule = result.data
	const expectedId = specialFlowModuleFields[field]
	if (parsedModule.id !== expectedId) {
		throw new Error(`Invalid ${field}: id must be "${expectedId}"`)
	}

	if (parsedModule.value.type !== 'rawscript' && parsedModule.value.type !== 'script') {
		throw new Error(`Invalid ${field}: only "rawscript" and "script" modules are supported`)
	}

	return parsedModule
}

const patchFlowJsonSchema = z.object({
	old_string: z.string().min(1).describe('Exact text to find in the current compact flow JSON'),
	new_string: z.string().describe('Replacement JSON text'),
	replace_all: z
		.boolean()
		.optional()
		.default(false)
		.describe(
			'When true, replace every exact match. When false, the search text must match exactly once.'
		)
})

const patchFlowJsonToolDef = createToolDef(

View on GitHub (pinned to e474e8803c)

Solutions

  1. Replace the module's value with a 'rawscript' or 'script' module (content, language, plus input schema for rawscript).
  2. Move the non-script logic into a script module and reference external resources from the script instead.
  3. If a subflow is genuinely needed, restructure so the special slot calls a script that triggers the flow.

Example fix

// before
"value": { "type": "flow", "path": "f/sub" }
// after
"value": { "type": "rawscript", "language": "python", "content": "...", "input_transforms": {} }
Defensive patterns

Strategy: validation

Validate before calling

if (module.value.type !== 'rawscript' && module.value.type !== 'script') {
  throw new Error('Special module must be a rawscript or script module')
}

Type guard

function isScriptModuleValue(v: { type: string }): v is { type: 'rawscript' | 'script' } {
  return v.type === 'rawscript' || v.type === 'script'
}

Try / catch

try {
  await tool.updateSpecialModule(field, module)
} catch (e) {
  if (e.message.includes('only "rawscript" and "script"')) {
    return requestModelRetry('Convert the module to a rawscript or script module.')
  }
  throw e
}

Prevention

When it happens

Trigger: The module passed for `field` has value.type of e.g. 'flow', 'loop', 'aiagent', 'http', 'identity', or another non-script module type.

Common situations: Model generated a nested flow or a non-script module for a slot that must run code; caller copied a generic flow module into a special field; attempt to wrap subflows where a script is required.

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/9d3141ed7aef3900. Report an issue: GitHub.