{"id":"f86468bc07d99a64","repo":"vitest-dev/vitest","slug":"cannot-read-file-when-saving-inline-snapshot","errorCode":null,"errorMessage":"cannot read ${file} when saving inline snapshot","messagePattern":"cannot read (.+?) when saving inline snapshot","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/snapshot/src/port/inlineSnapshot.ts","lineNumber":34,"sourceCode":"  column: number\n  // it maybe possible to accurately extract this from `ParsedStack.method`,\n  // but for now, we ask higher level assertion to pass it explicitly\n  // since this is useful for certain error messages before we extract stack.\n  assertionName?: string\n}\n\nexport async function saveInlineSnapshots(\n  environment: SnapshotEnvironment,\n  snapshots: Array<InlineSnapshot>,\n): Promise<void> {\n  const MagicString = (await import('magic-string')).default\n  const files = new Set(snapshots.map(i => i.file))\n  await Promise.all(\n    Array.from(files).map(async (file) => {\n      const snaps = snapshots.filter(i => i.file === file)\n      const code = await environment.readSnapshotFile(file)\n      if (code == null) {\n        throw new Error(`cannot read ${file} when saving inline snapshot`)\n      }\n\n      const s = new MagicString(code)\n\n      for (const snap of snaps) {\n        const index = positionToOffset(code, snap.line, snap.column)\n        replaceInlineSnap(code, s, index, snap.snapshot, snap.assertionName)\n      }\n\n      const transformed = s.toString()\n      if (transformed !== code) {\n        await environment.saveSnapshotFile(file, transformed)\n      }\n    }),\n  )\n}\n\nconst defaultStartObjectRegex","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/snapshot/src/port/inlineSnapshot.ts#L16-L52","documentation":"Thrown by saveInlineSnapshots() when environment.readSnapshotFile(file) returns null while writing back inline snapshots during --update or first write. readSnapshotFile returns null when the file does not exist or is not readable on the host; saving an inline snapshot requires reading the source to rewrite it in place, so a missing source file aborts the operation.","triggerScenarios":"Running vitest -u on a test file that was deleted between collection and write; custom SnapshotEnvironment.readSnapshotFile returning null; filesystem permissions or a race where the file is removed mid-run; running inline snapshot updates through a virtual filesystem that doesn't expose the source.","commonSituations":"IDE or watcher deleting/renaming a file while vitest is updating; misconfigured roots causing the resolved file path to point at a non-existent location; in-memory test setups (runInlineTests) that forget to register the source file with the environment.","solutions":["Verify the test file exists on disk at the path shown in the error before re-running vitest -u.","If using a custom SnapshotEnvironment, ensure readSnapshotFile returns the file's source string (not null) for existing files.","Avoid deleting or moving spec files during a running vitest watch/update session.","Re-run the update once the filesystem is stable."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { existsSync } from 'node:fs'\nif (!existsSync(file)) {\n  throw new Error(`source file missing before inline snapshot update: ${file}`)\n}","typeGuard":null,"tryCatchPattern":"try {\n  await vitest.runInlineTests({...})\n} catch (err) {\n  if (err.message.includes('cannot read') && err.message.includes('saving inline snapshot')) {\n    // file removed mid-run; recreate it and re-run vitest -u\n  } else throw err\n}","preventionTips":["Don't delete or move spec files while vitest -u/watch is running.","In custom SnapshotEnvironment implementations, ensure readSnapshotFile returns the source for existing files.","Pin file paths to absolute resolved paths to avoid roots mismatch."],"tags":["snapshot","inline-snapshot","filesystem"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}