{"id":"b2911ac517c8f613","repo":"jestjs/jest","slug":"jest-no-snapshot-insert-location-found","errorCode":null,"errorMessage":"Jest: no snapshot insert location found","messagePattern":"Jest: no snapshot insert location found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-snapshot/src/utils.ts","lineNumber":271,"sourceCode":"\n  if (!ast) {\n    throw new Error(`jest-snapshot: Failed to parse ${sourceFilePath}`);\n  }\n  traverseAst(snapshots, ast, snapshotMatcherNames);\n\n  return {\n    snapshotMatcherNames,\n    sourceFile,\n    // substitute in the snapshots in reverse order, so slice calculations aren't thrown off.\n    sourceFileWithSnapshots: snapshots.reduceRight(\n      (sourceSoFar, nextSnapshot) => {\n        const {node} = nextSnapshot;\n        if (\n          !node ||\n          typeof node.start !== 'number' ||\n          typeof node.end !== 'number'\n        ) {\n          throw new Error('Jest: no snapshot insert location found');\n        }\n\n        // A hack to prevent unexpected line breaks in the generated code\n        node.loc!.end.line = node.loc!.start.line;\n\n        return (\n          sourceSoFar.slice(0, node.start) +\n          generate(node, {retainLines: true}).code.trim() +\n          sourceSoFar.slice(node.end)\n        );\n      },\n      sourceFile,\n    ),\n  };\n};\n\nexport const processPrettierAst = (\n  ast: File,","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-snapshot/src/utils.ts#L253-L289","documentation":"Thrown inside the inline-snapshot source-reconstruction loop (utils.ts:266-272) when a matched AST node is missing numeric `start`/`end` byte offsets. Babel normally attaches location info to every node; a node without `start`/`end` cannot be spliced back into the source string, so Jest aborts rather than corrupting the file.","triggerScenarios":"Hit when an inline-snapshot call-expression node returned by `traverseAst` has `node.start` or `node.end` that is not a number. This typically requires a non-standard babel plugin or transform that strips/removes location info from generated nodes, or a manually-constructed AST passed through `generate()`.","commonSituations":"A custom babel plugin in the transform pipeline that emits synthesized nodes without positions; an outdated `@babel/core`/`@babel/generator` version mismatch; a transform that rewrites call expressions and drops `loc`/`start`/`end`. Rarely seen with stock configurations.","solutions":["Audit custom babel plugins in the transform/babel config and ensure they preserve node location info (`{ ...path.node }` patterns can drop positions).","Align `@babel/core`, `@babel/generator`, and `@babel/types` to a single resolved version (`npm ls @babel/core`).","If unavoidable, avoid inline snapshots in the affected file (use `toMatchSnapshot` writing to a `.snap` file instead)."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// If authoring a babel plugin in the transform chain, assert nodes carry positions\nconst hasLoc = node => typeof node?.start === 'number' && typeof node?.end === 'number';\nif (!hasLoc(callExprNode)) throw new Error('plugin dropped node positions');","typeGuard":"const nodeHasPositions = (n: any): boolean =>\n  n != null && typeof n.start === 'number' && typeof n.end === 'number';","tryCatchPattern":null,"preventionTips":["Prefer using `toMatchSnapshot()` (file-based) when running through non-standard babel plugins.","Keep `@babel/*` packages at a single resolved version (`npm ls @babel/core`).","Avoid plugins that synthesize replacement nodes without copying `loc`/`start`/`end`."],"tags":["jest-snapshot","babel","inline-snapshot","ast"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}