n8n-io/n8n · error · Error

Invalid response from Python script. Expected…

Error message

Invalid response from Python script. Expected WorkflowSimilarityResult shape but got: ${stdout.slice(0, 200)}

What it means

Schema-validation error in evaluateWorkflowSimilarity. It fires after JSON.parse succeeded but the parsed object fails the isWorkflowSimilarityResult type guard — the script emitted JSON that is not the expected result shape. The first 200 characters of stdout are included for diagnosis.

Solutions

  1. Check the Python script and uvx environment; the script exited 0 but printed non-JSON or wrong-shaped output.
  2. Run the same uvx command manually and inspect stdout for warnings or progress text polluting the JSON.
  3. Pin/refresh the similarity script's dependencies so its output schema matches isWorkflowSimilarityResult.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/@n8n/ai-workflow-builder.ee/evaluations/programmatic/evaluators/workflow-similarity.ts:170 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/e4b36c8f0080c822. Report an issue: GitHub.

Appendix: source

Thrown at packages/@n8n/ai-workflow-builder.ee/evaluations/programmatic/evaluators/workflow-similarity.ts:170

			// Only throw if we don't have valid output
			if (!stdout || stdout.trim() === '') {
				throw execError;
			}
		}

		// Check if stdout is empty
		if (!stdout || stdout.trim() === '') {
			throw new Error(
				`Python script produced no output. stderr: ${stderr || 'none'}. Command: uvx ${args.join(' ')}`,
			);
		}

		// Parse result
		const parsed: unknown = JSON.parse(stdout);

		if (!isWorkflowSimilarityResult(parsed)) {
			throw new Error(
				`Invalid response from Python script. Expected WorkflowSimilarityResult shape but got: ${stdout.slice(0, 200)}`,
			);
		}

		// Convert Python result to SingleEvaluatorResult format
		const violations = parsed.top_edits.map((edit) => ({
			name: mapEditTypeToViolationName(edit.type),
			type: edit.priority,
			description: edit.description,
			pointsDeducted: Math.round(edit.cost),
		}));

		return {
			violations,
			score: parsed.similarity_score,
		};
	} catch (error) {
		// Handle specific error cases

View on GitHub (pinned to 5ac6606e81)