n8n-io/n8n · error · Error

Failed to parse ${label} at ${path}: ${msg}

Error message

Failed to parse ${label} at ${path}: ${msg}

What it means

A generic JSON-parse helper (readJson) used by the MCP builder. It reads a file, attempts JSON.parse, and on failure wraps the underlying SyntaxError with the file label and path so the operator knows which file is malformed. Common callers are the ~/.claude.json loader and staged MCP config files.

Source

Thrown at packages/@n8n/instance-ai/evaluations/cli/mcp-builder.ts:46

// MCP config staging — the `--mcp-config` file `claude -p` is pointed at
// ---------------------------------------------------------------------------

const claudeConfigSchema = z
	.object({
		mcpServers: z.record(z.unknown()).optional(),
		projects: z
			.record(z.object({ mcpServers: z.record(z.unknown()).optional() }).passthrough())
			.optional(),
	})
	.passthrough();

function readJson(path: string, label: string): unknown {
	const content = readFileSync(path, 'utf-8');
	try {
		return JSON.parse(content);
	} catch (error) {
		const msg = error instanceof Error ? error.message : String(error);
		throw new Error(`Failed to parse ${label} at ${path}: ${msg}`);
	}
}

function uniqueDefined(values: Array<string | undefined>): string[] {
	const unique: string[] = [];
	for (const value of values) {
		if (!value || unique.includes(value)) continue;
		unique.push(value);
	}
	return unique;
}

/** Deduplicate project scopes (repo root, build cwd, process cwd) for the lookup. */
export function uniqueProjectScopes(scopes: Array<string | undefined>): string[] {
	return uniqueDefined(scopes);
}

// Every staged config embeds a bearer token, so exit cleanup is intrinsic to

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Open the path named in the message and run it through a JSON linter to find the syntax error.
  2. Restore the file from a known-good backup or regenerate it via the tool that owns it (e.g. claude code for ~/.claude.json).
  3. Validate JSON in your editor with a JSON language server before saving.

Example fix

// before: { "mcpServers": { "n8n": { ... } } , }
// after:  { "mcpServers": { "n8n": { ... } } }
Defensive patterns

Strategy: validation

Validate before calling

function readJsonChecked(path: string, label: string): unknown {
  const text = readFileSync(path, 'utf-8');
  try { return JSON.parse(text); }
  catch { throw new Error(`${label} at ${path} is invalid JSON`); }
}
// or pre-validate: JSON.parse(readFileSync(path,'utf-8')) in a try at call site

Type guard

const isRecord = (v: unknown): v is Record<string, unknown> =>
  typeof v === 'object' && v !== null && !Array.isArray(v);

Try / catch

try { return readJson(path, label); } catch (e) {
  if (e instanceof Error && e.message.startsWith('Failed to parse')) { /* restore backup */ }
  else throw e;
}

Prevention

When it happens

Trigger: Hand-editing ~/.claude.json or a staged MCP config and leaving a trailing comma, unquoted key, or unterminated object; a partial write left on disk after a crash.

Common situations: Manual edits to Claude Code config; merge-conflict resolution artifacts left in JSON; tooling that writes JSON without pretty-printing producing invalid output.

Understand the failure class

Related errors


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