n8n-io/n8n · error · Error
Failed to parse discovery test case ${filePath}: ${error ins
Error message
Failed to parse discovery test case ${filePath}: ${error instanceof Error ? error.message : String(error)} What it means
Thrown by `parseTestCaseFile()` in data/discovery/index.ts when `JSON.parse()` throws on a discovery test-case file. This is a pure syntax/lexing failure — unmatched braces, trailing commas (forbidden in strict JSON), single-quoted strings, control characters, or a truncated file. The original parse error is appended so the developer sees the JSON-level cause (line/column). Once parsing succeeds, the file is handed to `discoveryTestCaseSchema.safeParse`, which is a different failure path (error 430).
Source
Thrown at packages/@n8n/instance-ai/evaluations/data/discovery/index.ts:70
}),
rationale: z.string().optional(),
maxSteps: z.number().int().positive().optional(),
})
.strict();
export interface DiscoveryTestCaseWithFile {
testCase: DiscoveryTestCase;
/** Filename without extension, e.g. "slack-oauth-credential-setup" */
fileSlug: string;
}
function parseTestCaseFile(filePath: string): DiscoveryTestCase {
const content = readFileSync(filePath, 'utf-8');
let raw: unknown;
try {
raw = JSON.parse(content);
} catch (error) {
throw new Error(
`Failed to parse discovery test case ${filePath}: ${error instanceof Error ? error.message : String(error)}`,
);
}
const parsed = discoveryTestCaseSchema.safeParse(raw);
if (!parsed.success) {
const issues = parsed.error.issues
.map((issue) => `${issue.path.join('.') || '(root)'}: ${issue.message}`)
.join('; ');
throw new Error(`Invalid discovery test case ${filePath}: ${issues}`);
}
return parsed.data;
}
function parseSubstringList(value: string | undefined): string[] {
if (!value) return [];
return value
.split(',')
.map((s) => s.trim().toLowerCase())View on GitHub (pinned to 5ac6606e81)
Solutions
- Open the file at the path in the error and fix the JSON syntax error cited in the message (line/column from the underlying SyntaxError).
- Validate with a linter: `npx jsonlint <file>` or your editor's JSON language server to find the exact position.
- Remove comments, trailing commas, and single quotes; ensure strings use double quotes.
- If the file was truncated, restore from git: `git checkout HEAD -- <file>`.
Example fix
// before (case.json — invalid)
{
"id": "slack-setup",
// trailing comma below:
"userMessage": "hi",
}
// after
{
"id": "slack-setup",
"userMessage": "hi"
} Defensive patterns
Strategy: try-catch
Validate before calling
import { readFileSync } from 'fs';
function tryParseJson(filePath: string): unknown {
try {
return JSON.parse(readFileSync(filePath, 'utf-8'));
} catch (e) {
throw new Error(`${filePath}: ${(e as Error).message}`);
}
} Try / catch
try {
raw = JSON.parse(content);
} catch (error) {
// already the path this loader takes — augment with file context
throw new Error(`Failed to parse discovery test case ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
} Prevention
- Lint all case JSON in CI (`jsonlint` or equivalent) so syntax errors fail before any code runs.
- Configure editors to reject trailing commas / comments in `.json` files.
- Use `git status` after merges to confirm no conflict markers leaked into JSON.
When it happens
Trigger: Hand-edited discovery case file with a trailing comma or comment. A file truncated by a crashed editor or a bad git merge. A file saved as JSONC or JSON5 (this loader uses strict `JSON.parse`). A BOM or CRLF issue on Windows-edited files in rare cases. A copy-paste that introduced smart quotes.
Common situations: Authoring a new discovery case and forgetting JSON's strictness (no comments, no trailing commas). A merge conflict marker left in the file. An editor that auto-inserted a trailing comma.
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
- Invalid discovery test case ${filePath}: ${issues}
- Failed to parse ${label} at ${path}: ${msg}
- Existing manifest at ${manifestPath} is malformed; remove or
- expectedToolInvocations must specify a non-empty `anyOf`, `n
- Nested ${Array.isArray(value) ? 'array' : 'object'} found at
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/753aaa1ad7eda90e.
Report an issue: GitHub.