windmill-labs/windmill · error

Cannot test step of type "${moduleValue.type}". Supported ty

Error message

Cannot test step of type "${moduleValue.type}". Supported types: rawscript, script, flow

What it means

The copilot's step-test tool in shared.ts can only run test executions of rawscript, script, and flow module types. When the AI agent asks to test a step whose module type falls outside that set (e.g. 'approval', 'sleep', 'wait', 'loop', 'branch', 'forloop'), the tool marks itself failed in the UI and throws this Error instead of calling the job APIs. It is a deliberate guard: only these three types map to a directly runnable job.

Source

Thrown at frontend/src/lib/components/copilot/chat/shared.ts:2004

					path: moduleValue.path,
					requestBody: stepArgs
				}),
			workspace,
			toolCallbacks,
			toolId,
			startMessage: `Starting test run of flow step "${stepId}"...`,
			contextName: 'flow',
			label: `step ${stepId}`,
			background,
			detachAfterMs
		})
	}

	toolCallbacks.setToolStatus(toolId, {
		content: `Step type "${moduleValue.type}" not supported for testing`,
		error: `Cannot test step of type "${moduleValue.type}"`
	})
	throw new Error(
		`Cannot test step of type "${moduleValue.type}". Supported types: rawscript, script, flow`
	)
}

function formatLogs(logs: string | undefined): undefined | string {
	if (logs && logs.trim()) {
		if (logs.length <= MAX_LOG_LENGTH) {
			return logs
		} else {
			return logs.slice(-MAX_LOG_LENGTH)
		}
	}
	return undefined
}

function formatResult(result: unknown): string {
	if (typeof result === 'string') {
		return result

View on GitHub (pinned to e474e8803c)

Solutions

  1. Test the step's parent flow instead, so all node types execute in context
  2. Manually run the step's underlying script/flow from the Windmill UI if it is a script-like module
  3. If you are extending the tool, add a branch for the new module type that maps it to a runnable job (as done for rawscript/script/flow above the throw)

Example fix

// agent asked to test an approval step
// before (throws)
testStep({ stepId: 'approval_1' })
// after: run the enclosing flow
runFlowPreview({ path: 'f/flows/my_flow', args: {} })
Defensive patterns

Strategy: type-guard

Validate before calling

const TESTABLE_TYPES = ['rawscript', 'script', 'flow']
if (!TESTABLE_TYPES.includes(moduleValue.type)) {
  // route to running the whole flow instead of the single step
}

Type guard

function isTestableStep(m: { type: string }): m is { type: 'rawscript' | 'script' | 'flow' } {
  return ['rawscript', 'script', 'flow'].includes(m.type)
}

Try / catch

try {
  await testStep({ stepId })
} catch (e) {
  if (String(e.message).startsWith('Cannot test step of type')) {
    await runFlowPreview({ path: flowPath, args: {} })
  } else throw e
}

Prevention

When it happens

Trigger: A copilot agent invokes the test-run tool on a flow step whose underlying module has type like 'approval', 'sleep', 'branch', 'loop', or 'whileloop' — any type not in {rawscript, script, flow}. moduleValue.type comes from the loaded flow module, so editing/wrapping step types in the editor then asking the chat to 'test this step' hits it.

Common situations: User selects a subflow/loop/approval step in the flow editor and asks the copilot to test it; a script was converted to another module type and the agent still targets it; a flow preview that only contains non-runnable nodes.

Related errors


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