n8n-io/n8n · error · Error

Failed to read prebuilt-workflows manifest at ${path}: ${msg

Error message

Failed to read prebuilt-workflows manifest at ${path}: ${msg}

What it means

Thrown by loadPrebuiltManifest when readFileSync or JSON.parse fails on the manifest path — the file is missing, unreadable, or not valid JSON. The error wraps the underlying filesystem/parse error message so the caller can see the exact OS/parse cause.

Source

Thrown at packages/@n8n/instance-ai/evaluations/harness/prebuilt-workflows.ts:39

import { z } from 'zod';

import type { BuildResult } from './build-workflow';
import type { EvalLogger } from './logger';
import type { N8nClient } from '../clients/n8n-client';

export const prebuiltManifestSchema = z
	.record(z.string().min(1), z.array(z.string().min(1)).min(1))
	.refine((v) => Object.keys(v).length > 0, { message: 'manifest must not be empty' });

export type PrebuiltManifest = z.infer<typeof prebuiltManifestSchema>;

export function loadPrebuiltManifest(path: string): PrebuiltManifest {
	let raw: unknown;
	try {
		raw = JSON.parse(readFileSync(path, 'utf-8'));
	} catch (error) {
		const msg = error instanceof Error ? error.message : String(error);
		throw new Error(`Failed to read prebuilt-workflows manifest at ${path}: ${msg}`);
	}
	const result = prebuiltManifestSchema.safeParse(raw);
	if (!result.success) {
		throw new Error(
			`Invalid prebuilt-workflows manifest at ${path}: ${result.error.issues
				.map((i) => `${i.path.join('.')}: ${i.message}`)
				.join('; ')}`,
		);
	}
	return result.data;
}

/**
 * Look up the workflow ID for a given test-case file slug + iteration.
 *
 * Returns `undefined` in two cases — callers cannot distinguish them and
 * shouldn't need to:
 *   • the manifest argument itself is undefined (no `--prebuilt-workflows`)

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Check the underlying error message embedded in the thrown string (e.g. ENOENT, EACCES, Unexpected token) to classify the cause.
  2. Verify the path exists and is a file: `fs.statSync(path).isFile()`.
  3. If missing, generate or regenerate the manifest (run the project's manifest-generation step).
  4. If malformed, validate the JSON with a linter/editor and fix the syntax error.

Example fix

// before
loadPrebuiltManifest('./prebuilt-workflows.json');

// after — verify existence and provide a clear fallback path
const path = './prebuilt-workflows.json';
if (!fs.existsSync(path)) throw new Error(`manifest missing at ${path}; run the generator first`);
loadPrebuiltManifest(path);
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync, statSync } from 'node:fs';

function manifestReadable(path: string): boolean {
  try {
    return existsSync(path) && statSync(path).isFile();
  } catch {
    return false;
  }
}

if (!manifestReadable(path)) {
  throw new Error(`manifest not readable at ${path}; generate it first`);
}

Type guard

function isManifestReadError(e: unknown): boolean {
  return e instanceof Error && e.message.startsWith('Failed to read prebuilt-workflows manifest at ');
}

Try / catch

try {
  loadPrebuiltManifest(path);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Failed to read prebuilt-workflows manifest')) {
    // regenerate or fall back to a known-good path
  }
  throw e;
}

Prevention

When it happens

Trigger: The manifest path does not exist; the path points at a directory; insufficient read permissions; the file exists but contains malformed JSON (trailing comma, unquoted keys, BOM issues).

Common situations: CI checkout missing the generated manifest file; relative path resolved against an unexpected cwd; the manifest was hand-edited and broke JSON syntax; the file was gitignored and not committed.

Related errors


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