{"id":"17ecef18e8aeb0a7","repo":"vitest-dev/vitest","slug":"snapshot-keys-must-end-with-a-number","errorCode":null,"errorMessage":"Snapshot keys must end with a number.","messagePattern":"Snapshot keys must end with a number\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/snapshot/src/port/utils.ts","lineNumber":24,"sourceCode":" */\n\nimport type { OptionsReceived as PrettyFormatOptions } from '@vitest/pretty-format'\nimport type { SnapshotData, SnapshotStateOptions } from '../types'\nimport type { SnapshotEnvironment } from '../types/environment'\nimport { format as prettyFormat } from '@vitest/pretty-format'\nimport { isObject } from '@vitest/utils/helpers'\nimport naturalCompare from 'natural-compare'\nimport { getSerializers } from './plugins'\n\n// TODO: rewrite and clean up\n\nexport function testNameToKey(testName: string, count: number): string {\n  return `${testName} ${count}`\n}\n\nexport function keyToTestName(key: string): string {\n  if (!/ \\d+$/.test(key)) {\n    throw new Error('Snapshot keys must end with a number.')\n  }\n\n  return key.replace(/ \\d+$/, '')\n}\n\nexport function getSnapshotData(\n  content: string | null,\n  options: SnapshotStateOptions,\n): {\n  data: SnapshotData\n  dirty: boolean\n} {\n  const update = options.updateSnapshot\n  const data = Object.create(null)\n  let snapshotContents = ''\n  let dirty = false\n\n  if (content != null) {","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/snapshot/src/port/utils.ts#L6-L42","documentation":"Thrown by keyToTestName() in packages/snapshot/src/port/utils.ts when a snapshot key does not end with ' <number>'. Vitest stores snapshots keyed by `${testName} ${count}` (built by testNameToKey); the inverse parser uses the trailing-number regex to strip the counter. A key without it indicates a hand-edited, corrupted, or externally written snapshot file whose keys violate the format.","triggerScenarios":"Manually editing a .snap file and removing the trailing number; tooling that regenerates .snap files with non-standard keys; renaming tests so an old key no longer matches the testName N pattern; corrupted snapshot file from a partial write.","commonSituations":"Merge conflicts in .snap files resolved incorrectly; third-party snapshot tooling that writes its own keys; pre-existing snapshots from an older Vitest/Jest version with a different convention; git operations that truncated a key.","solutions":["Delete the offending .snap file and regenerate it with vitest -u.","Open the .snap file cited by the error and fix or remove keys that don't end with ' <number>'.","Avoid hand-editing snapshot files; let Vitest write them.","Add .snap files to .gitattributes as binary or use a merge strategy that keeps one side, then re-run -u."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function isValidSnapshotKey(key: string): boolean {\n  return / \\d+$/.test(key)\n}","typeGuard":"const isValidSnapshotKey = (key: string): boolean => / \\d+$/.test(key)","tryCatchPattern":null,"preventionTips":["Never hand-edit .snap files; always regenerate via vitest -u.","Add .gitattributes merge=ours for *.snap to avoid merge conflicts producing malformed keys.","Audit third-party tooling that writes .snap files to ensure it uses the 'name N' convention."],"tags":["snapshot","snapshot-file","corruption"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}