vitest-dev / vitest-dev/vitest

fsModuleCache serves a stale transform after a dependency is renamed (Cannot find module)

Open
#11,246 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

p3-minor-bug
Dominant language
TypeScript
Stars
17.1k
Forks
2k
Avg merge
1d 22h
Merged PRs (30d)
94

Description

Describe the bug

With fsModuleCache: true, renaming a module that another module imports serves a stale transform of the importer, and the importer then fails with Cannot find module. This holds as long as the importer's own source is unchanged, which is the usual case when switching git branches.

The cached transform of the importer contains the resolved path of its import. The cache key covers the importer's id and content, the config file content and the plugin names, but not what the importer's imports resolve to. So after b.ts becomes b.tsx, a.ts hits the cache and still imports /src/b.ts.

Found by running a 643-file suite cold and then warm across a branch switch: 285 files failed to load with Cannot find module, and all of them passed again once node_modules/.vitest-cache was deleted.

Reproduction
src/a.ts        export { value } from './b';
src/b.ts        export const value = 1;
src/a.test.ts   import { value } from './a'; it('reads it', () => expect(value).toBe(1));
vitest.config.mjs  export default defineConfig({ test: { fsModuleCache: true } });
  1. vitest run passes. This run writes the cache.
  2. mv src/b.ts src/b.tsx. a.ts is untouched.
  3. vitest run fails:
    Error: Cannot find module '/src/b.ts' imported from …/src/a.ts
  4. rm -rf node_modules/.vitest-cache && vitest run passes.
Expected

Step 3 passes. A module's cache entry should be invalidated, or its resolved imports revalidated, when a dependency it resolved to no longer exists or now resolves elsewhere.

System info

vitest 5.0.0, vite 8.2.x, Node 24.16.0, Linux. The same happens with pool: forks (the default) and 1 worker.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the failure with src/a.ts, src/b.ts, src/a.test.ts, and vitest.config.mjs using fsModuleCache: true. Inspect how the cache entry for the importer records resolved imports, then verify that renaming src/b.ts to src/b.tsx no longer leaves a.ts pointing at the missing path. Confirm with the warm-cache reproduction and the clean-cache comparison.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript, vite
Domain
testing, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.