jestjs/jest · error · Error
Custom snapshot resolver functions must transform paths cons
Error message
Custom snapshot resolver functions must transform paths consistently, i.e. expects resolveTestPath(resolveSnapshotPath('${custom.testPathForConsistencyCheck}')) === ${resolvedTestPath} What it means
Thrown by `verifyConsistentTransformations` (SnapshotResolver.ts:120-131) when the custom resolver is not its own inverse: `resolveTestPath(resolveSnapshotPath(testPathForConsistencyCheck))` must equal `testPathForConsistencyCheck`. Jest needs round-trip consistency so it can map a snapshot file back to its test and vice versa without ambiguity.
Source
Thrown at packages/jest-snapshot/src/SnapshotResolver.ts:126
verifyConsistentTransformations(customResolver);
return customResolver;
}
function mustImplement(propName: string, requiredType: string) {
return `${chalk.bold(
`Custom snapshot resolver must implement a \`${propName}\` as a ${requiredType}.`,
)}\nDocumentation: https://jestjs.io/docs/configuration#snapshotresolver-string`;
}
function verifyConsistentTransformations(custom: SnapshotResolver) {
const resolvedSnapshotPath = custom.resolveSnapshotPath(
custom.testPathForConsistencyCheck,
);
const resolvedTestPath = custom.resolveTestPath(resolvedSnapshotPath);
if (resolvedTestPath !== custom.testPathForConsistencyCheck) {
throw new Error(
chalk.bold(
`Custom snapshot resolver functions must transform paths consistently, i.e. expects resolveTestPath(resolveSnapshotPath('${custom.testPathForConsistencyCheck}')) === ${resolvedTestPath}`,
),
);
}
}
View on GitHub (pinned to f49721c78e)
Solutions
- Make `resolveTestPath` the exact inverse of `resolveSnapshotPath` for every input — verify by hand with the consistency check path.
- Use the same string replacement in both directions (e.g. swap `.test.` and `.snap.` symmetrically).
- Add a unit test that asserts the round trip for several realistic paths.
- If you genuinely need a non-invertible mapping, reconsider whether a custom resolver is the right tool.
Example fix
// before — asymmetric mappings
resolveSnapshotPath: t => t.replace('test', 'snap'),
resolveTestPath: s => s.replace('snapshot', 'test'),
// after — symmetric, invertible
resolveSnapshotPath: t => t.replace(/\.test\./, '.snap.'),
resolveTestPath: s => s.replace(/\.snap\./, '.test.'), Defensive patterns
Strategy: validation
Validate before calling
const r = require('./snapshotResolver');
const t = r.testPathForConsistencyCheck;
const roundTrip = r.resolveTestPath(r.resolveSnapshotPath(t));
if (roundTrip !== t) {
throw new Error(`Resolver not invertible: ${t} -> ${roundTrip}`);
} Prevention
- Write the two functions as exact inverses and add a property test that round-trips many paths.
- Use simple symmetric replacements (e.g. swap extensions) rather than regex transforms that can drop characters.
- Re-run the consistency check in a unit test any time you touch the resolver.
When it happens
Trigger: A resolver that maps `a.test.js` → `__snapshots__/a.snap` but `resolveTestPath('__snapshots__/a.snap')` returns `a.spec.js`. Using different replacement tokens in the two directions. Regex-based resolvers that aren't strict inverses for the consistency check path.
Common situations: Hand-written resolver that handles the forward direction but ignores directory layout on the reverse. Resolver copied from another project with a different directory convention.
Related errors
- Custom snapshot resolver must implement a `${propName}` as a
- The --config option requires a JSON string literal, or a fil
- Cannot merge config in form of callback
- Whoops! Two projects resolved to the same config path: ${Str
- Jest: Cannot use configuration as an object without a file p
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/0222ec5a3553ecde.json.
Report an issue: GitHub.