jestjs/jest · error · Error
Cannot parse as JSON
Error message
Cannot parse ${filePath} as JSON: ${error.message} What it means
The haste-map worker reads and JSON.parses every `package.json` it encounters during the crawl to extract the package name as a haste ID. If `JSON.parse` throws (malformed JSON, trailing comma, BOM, comments), the worker re-throws a descriptive Error naming the file and the parse error message, with the original error attached as `cause`. This stops processing of that file.
Solutions
- Open the file named in the error message and run it through a JSON validator or `npx jsonlint <file>`.
- Fix the specific syntax error the embedded `${error.message}` describes (e.g. 'Unexpected token').
- If the file is in node_modules, reinstall the offending package: `npm ci`.
- Add the path to `modulePathIgnorePatterns` or `roots` exclusion if it is an unrelated generated file.
Example fix
// before — broken package.json
{
"name": "my-pkg",
"version": "1.0.0", // trailing comma
}
// after
{
"name": "my-pkg",
"version": "1.0.0"
} Defensive patterns
Strategy: type-guard
Validate before calling
// Validate every package.json in the crawl path before building.
import { readFileSync } from 'node:fs';
import glob from 'fast-glob';
function validatePackageJsons(rootDir: string) {
for (const file of glob.sync(`${rootDir}/**/package.json`, { ignore: '**/node_modules/**' })) {
try { JSON.parse(readFileSync(file, 'utf8')); }
catch (e) { throw new Error(`Invalid JSON in ${file}: ${(e as Error).message}`); }
}
} Type guard
function isValidJsonFile(filePath: string): boolean {
try { JSON.parse(readFileSync(filePath, 'utf8')); return true; }
catch { return false; }
} Prevention
- Run a JSON lint pass on all package.json files in CI.
- Add a pre-commit hook (e.g. `jsonlint`) for package.json edits.
- Reinstall node_modules (`npm ci`) if a node_modules package.json is corrupt.
When it happens
Trigger: worker() at worker.ts:49 checks `filePath.endsWith(PACKAGE_JSON)`, calls `JSON.parse(getContent())` at line 52, and the catch at line 59 re-throws the wrapped error at line 60. Any package.json with invalid JSON syntax triggers it.
Common situations: A hand-edited package.json with a trailing comma, single quotes, or a comment; a corrupted/truncated file from a failed git merge; a generated package.json with a NaN or unquoted key; node_modules package.json overwritten by a broken postinstall script.
Related errors
- Could not find a "package.json" file in
- Attempted to display seed but seed value is undefined
- babel-jest: Babel ignores
- Crawler retry failed: Original error
- Custom export conditions specified but they are not an…
AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10).
Data as JSON: /api/errors/7b9019af1116773c.
Report an issue: GitHub.
Appendix: source
Thrown at packages/jest-haste-map/src/worker.ts:60
if (content === undefined) {
content = fs.readFileSync(filePath, 'utf8');
}
return content;
};
if (filePath.endsWith(PACKAGE_JSON)) {
// Process a package.json that is returned as a PACKAGE type with its name.
try {
const fileData = JSON.parse(getContent());
if (fileData.name) {
const relativeFilePath = path.relative(rootDir, filePath);
id = fileData.name;
module = [relativeFilePath, H.PACKAGE];
}
} catch (error: any) {
throw new Error(`Cannot parse ${filePath} as JSON: ${error.message}`, {
cause: error,
});
}
} else if (!blacklist.has(filePath.slice(filePath.lastIndexOf('.')))) {
// Process a random file that is returned as a MODULE.
if (hasteImpl) {
id = hasteImpl.getHasteName(filePath);
}
if (computeDependencies) {
const content = getContent();
const extractor = data.dependencyExtractor
? await requireOrImportModule<DependencyExtractor>(
data.dependencyExtractor,
false,
)
: defaultDependencyExtractor;
dependencies = [View on GitHub (pinned to 8e6d128e4a)