Skip to content

[Start] virtual:tanstack-start-client-entry 404 in pnpm monorepo (regression on react-start@1.168 + vite@8) #7418

@ArthurSaenz

Description

@ArthurSaenz

Which project does this relate to?

Start

Bug

On a fresh install with @tanstack/react-start@1.168.0 + vite@8.0.13 in a pnpm monorepo (enableGlobalVirtualStore: true), every dev request to:

GET /@id/virtual:tanstack-start-client-entry

returns 404. Hydration fails (Uncaught (in promise) TypeError: Failed to fetch dynamically imported module) and the routed <Outlet /> renders empty — header and footer from the pathless layout show, the page body is blank.

This is the exact symptom of #6588 (closed, "fixed in v1.159.6" via #7178), so I'm filing this as a regression rather than commenting on the closed thread.

Repro

  • pnpm 11.x, Node 24.x, macOS
  • vite@8.0.13
  • @tanstack/react-start@1.168.0 → resolves start-plugin-core@1.170.0, start-server-core@1.168.0, start-client-core@1.169.0
  • pnpm-workspace.yaml: enableGlobalVirtualStore: true
  • Start the Vite dev server, open / in any browser

SSR HTML emits:

import("/@id/virtual:tanstack-start-client-entry")

Diagnosis

In Vite 8 the /@id/ middleware requires virtual-module URLs to carry the null-byte prefix encoded as __x00__ (or %00):

URL Status
/@id/virtual:tanstack-start-client-entry 404
/@id/__x00__virtual:tanstack-start-client-entry 200
/@id/%00virtual:tanstack-start-client-entry 200

start-plugin-core@1.170.0's createVirtualModule correctly returns the \0-prefixed resolvedId from its resolveId hook, but the SSR-emitted client bootstrap (from start-server-core@1.168.0) writes the bare-prefix URL into the HTML, so Vite 8's URL-to-id middleware never reaches the plugin's hook.

Workaround

Inline Vite plugin that rewrites the URL before resolution (works locally):

import { defineConfig, type Plugin } from 'vite'

const tanstackVirtualUrlShim = (): Plugin => ({
  name: 'tanstack-start:virtual-url-shim',
  enforce: 'pre',
  configureServer(server) {
    server.middlewares.use((req, _res, next) => {
      if (req.url?.startsWith('/@id/virtual:tanstack-')) {
        req.url = req.url.replace('/@id/virtual:', '/@id/__x00__virtual:')
      }
      next()
    })
  },
})

export default defineConfig({
  plugins: [tanstackVirtualUrlShim(), /* ...rest */],
})

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions