n8n-io/n8n · error · Error

--delete-prebuilt-workflows cannot be used with --keep-workf

Error message

--delete-prebuilt-workflows cannot be used with --keep-workflows

What it means

Thrown by parseCliArgs() when both --delete-prebuilt-workflows and --keep-workflows are set. The two flags are logically contradictory: one deletes successfully-used workflows after evaluation, the other retains all built workflows. The parser refuses the combination so the run's intent is unambiguous.

Source

Thrown at packages/@n8n/instance-ai/evaluations/cli/args.ts:209

	// lanes × iterations × 4 and flood the shared Anthropic budget. Fail fast
	// instead of teaching the direct loop (tech debt slated for removal) MCP builds.
	if (validated.buildViaMcp && !process.env.LANGSMITH_API_KEY) {
		throw new Error(
			'--build-via-mcp requires LangSmith experiment tracking — set LANGSMITH_API_KEY. The no-LangSmith direct loop does not support MCP builds.',
		);
	}
	// Build knobs without --build-via-mcp would parse fine and then be silently
	// ignored — the run would look like it honored them. Fail loudly instead.
	if (!validated.buildViaMcp && raw.buildOnlyFlags.length > 0) {
		throw new Error(
			`${[...new Set(raw.buildOnlyFlags)].join(', ')} only take${raw.buildOnlyFlags.length === 1 ? 's' : ''} effect with --build-via-mcp — pass it, or drop the flag(s).`,
		);
	}
	if (validated.deletePrebuiltWorkflows && !validated.prebuiltWorkflows) {
		throw new Error('--delete-prebuilt-workflows requires --prebuilt-workflows');
	}
	if (validated.deletePrebuiltWorkflows && validated.keepWorkflows) {
		throw new Error('--delete-prebuilt-workflows cannot be used with --keep-workflows');
	}
	if (validated.source === 'langtracer' && !validated.suite) {
		throw new Error('--source langtracer requires --suite <slug>');
	}

	// In langtracer mode, default the dataset + baseline to a suite-scoped, eval-tagged
	// name so runs don't pollute the shared cohort and re-runs upsert one stable dataset.
	let dataset = validated.dataset;
	let datasetAutoForked = false;
	let baselinePrefix = validated.baselinePrefix;
	if (validated.source === 'langtracer' && validated.suite) {
		const suiteSlug = validated.suite
			.toLowerCase()
			.replace(/[^a-z0-9]+/g, '-')
			.replace(/^-+|-+$/g, '');
		if (!raw.datasetProvided) {
			dataset = `instance-ai-langtracer-${suiteSlug}`;
			datasetAutoForked = true;

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Remove --delete-prebuilt-workflows if you want to keep all workflows.
  2. Remove --keep-workflows if you want pre-built workflows deleted after use.

Example fix

// before
pnpm eval:instance-ai --prebuilt-workflows ./manifest.json --keep-workflows --delete-prebuilt-workflows
// after (keep all)
pnpm eval:instance-ai --prebuilt-workflows ./manifest.json --keep-workflows
// after (delete used prebuilt workflows)
pnpm eval:instance-ai --prebuilt-workflows ./manifest.json --delete-prebuilt-workflows
Defensive patterns

Strategy: validation

Validate before calling

function validateNoKeepDeleteConflict(args: string[]): void {
  if (args.includes('--keep-workflows') && args.includes('--delete-prebuilt-workflows')) {
    throw new Error('--keep-workflows and --delete-prebuilt-workflows are mutually exclusive');
  }
}

Prevention

When it happens

Trigger: Invoking the eval CLI with both flags simultaneously: `... --keep-workflows --delete-prebuilt-workflows`. The check fires at args.ts:208.

Common situations: A developer merges two command templates (one for keeping, one for deleting) and forgets to reconcile them, or toggles flags while debugging and leaves both active.

Related errors


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