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 toView on GitHub (pinned to 5ac6606e81)
Solutions
- Open the path named in the message and run it through a JSON linter to find the syntax error.
- Restore the file from a known-good backup or regenerate it via the tool that owns it (e.g. claude code for ~/.claude.json).
- 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
- Never hand-edit JSON; use a tool that writes valid JSON.
- Add a JSON schema check in CI for config files.
- Keep backups of config files for quick restore.
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to parse query: ${(error as Error).message}
- MCP server "${cfg.name}": exactly one of "url" or "command"
- MCP server "${cfg.name}": provide either "url" or "command",
- MCP server name "${cfg.name}" is already registered
- Failed to parse judge response as JSON: ${jsonStr.slice(0, 1
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/b9adf8ff5690adb5.
Report an issue: GitHub.