Skip to content

Dev server keeps stale import URL for importers after a file rename ("Does the file exist?") #23527

Description

@Addin

Describe the bug

When a module file is renamed while the dev server is running, its importers keep the old resolved URL for the deleted file. Any request to that stale URL fails with:

Pre-transform error: Failed to load url /src/dep.ts (resolved id: /app/src/dep.ts) in /app/src/main.ts. Does the file exist?

In an app this breaks the module graph (a React app never mounts and the page stays blank). A full page reload does not recover it; restarting the dev server does. Touching/editing the importer also recovers it, which suggests the importer's cached transform keeps the old resolution until it is invalidated again.

Reproduction

Minimal project:

.
├── index.html          <div id="app"></div><script type="module" src="/src/main.ts"></script>
└── src
    ├── main.ts         import { value } from "./dep"; console.log(value);
    └── dep.ts          export const value = 1;
  1. Start the dev server and request the importer:
    curl -s http://localhost:5173/src/main.ts
    # => import { value } from "/src/dep.ts";
    
  2. Rename the dependency (same module, new extension):
    mv src/dep.ts src/dep.tsx
    
  3. Request the importer again:
    curl -s http://localhost:5173/src/main.ts
    # => import { value } from "/src/dep.ts?t=1789840891492";   <-- stale, the file no longer exists
    
  4. Request the stale URL:
    curl -s http://localhost:5173/src/dep.ts
    # dev server logs: Pre-transform error: Failed to load url /src/dep.ts ... Does the file exist?
    
  5. Re-invalidate the importer and it resolves correctly again:
    touch src/main.ts
    curl -s http://localhost:5173/src/main.ts
    # => import { value } from "/src/dep.tsx";
    

I also hit this in a real app by switching git branches where a file was renamed (.ts.tsx): the page went blank, opening a new tab did not help, and only a dev-server restart recovered it.

Expected behavior

Renaming a module should invalidate its importers so they resolve to the new path (and the usual page reload/HMR kicks in), without having to restart the dev server.

System Info

System:
  OS: Linux
  Node: v26.9.0 (also observed in a node:26 container)
  Package Manager: pnpm 11.9.0
  Browser: Edge (Chromium)

Binaries:
  vite: 8.1.3 and 8.3.0

Used Package Manager

pnpm

Logs

8:02:31 PM [vite] (client) page reload src/dep.ts
8:02:34 PM [vite] (client) Pre-transform error: Failed to load url /src/dep.ts (resolved id: /tmp/vite-rename-repro/src/dep.ts) in /tmp/vite-rename-repro/src/main.ts. Does the file exist?

Additional context

  • Reproduced with the default watcher and with server.watch.usePolling: true.
  • Reproduced with vite 8.1.3 (pinned in our project) and 8.3.0 (latest at the time of writing).
  • The dev server does notice the deletion (page reload src/dep.ts is logged), but the re-served importer still imports the deleted path (with a ?t= cache-busting query). Requesting that URL produces the pre-transform error above.
  • Related but different: Imports outside of the root break on file rename #16399 (closed) is about imports outside the root and required manually fixing the import; here nothing is edited and the import specifier (./dep) is unchanged.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions