[GH-ISSUE #853] @vitejs/plugin-rsc serverHandler middleware crashes on environment.runner.import when nitro/vite plugin is present #186

Open
opened 2026-05-06 12:37:57 +02:00 by BreizhHardware · 1 comment

Originally created by @jlucaso1 on GitHub (Apr 16, 2026).
Original GitHub issue: https://github.com/cloudflare/vinext/issues/853

Summary

When vinext is used together with nitro/vite (as shown in vinext's own setup for deployment), every request to the dev server returns a 500 with:

[vite] Internal server error: Cannot read properties of undefined (reading 'import')
  at …/@vitejs/plugin-rsc/dist/plugin-DMfc_Eqq.js:784:76

Versions

  • vinext@0.0.41
  • @vitejs/plugin-rsc@0.5.24
  • vite@8.0.8
  • nitronitro-nightly@3.0.1-20260311-140511-1d05f55f
  • Node v22.22.1, pnpm 10.28.2

Reproduction

Minimal vite.config.ts:

import vinext from 'vinext';
import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'vite';
import { nitro } from 'nitro/vite';

export default defineConfig({
  plugins: [tailwindcss(), vinext(), nitro({ noExternals: ['tslib'] })],
});

App with a Next.js App Router layout. pnpm dev → any request to / fails.

Logs

1:50:19 PM [vite] Internal server error: Cannot read properties of undefined (reading 'import')
      at file:///…/@vitejs+plugin-rsc@0.5.24_…/node_modules/@vitejs/plugin-rsc/dist/plugin-DMfc_Eqq.js:784:76
 GET / 500 in 3ms
 GET /warehouse-requests 500 in 2ms
 GET /payment-requests?priority=urgent 500 in 2ms
 GET /payment-receipts 500 in 3ms
 GET /kanban 500 in 2ms

The same error repeats for every route.

Root cause (as far as I can trace)

@vitejs/plugin-rsc@0.5.24 registers a configureServer middleware that does:

// @vitejs/plugin-rsc/dist/plugin-DMfc_Eqq.js around L784
const environment = server.environments[options.environmentName]; // "rsc"
const resolved = await environment.pluginContainer.resolveId(source);
const fetchHandler = getFetchHandlerExport(
  await environment.runner.import(resolved.id)   // ← crashes here
);

This path assumes environment is a RunnableDevEnvironment. When nitro/vite is in the plugin chain, nitro's env factory (createFetchableDevEnvironment in nitro-nightly/dist/vite.mjs) replaces some environments with a FetchableDevEnvironment subclass that does not have a .runner — it exposes fetchModule() / devServer.fetch instead. So environment.runner is undefined and the next property access (.import) throws.

Elsewhere in plugin-rsc (in the import.meta.viteRsc.import path), the code does guard with vite.isRunnableDevEnvironment(environment) before accessing .runner. The configureServer middleware and configurePreviewServer paths don't have that guard.

Interestingly, vinext itself already documents this exact situation in vinext/dist/server/dev-module-runner.js (comment preserved from source):

When @cloudflare/vite-plugin is present it registers its own Vite environments (e.g. "rsc", "ssr") that are not RunnableDevEnvironment instances. Calling ssrLoadModule() in that context crashes…

…and provides a fetchModule()-based workaround, but that workaround isn't wired into plugin-rsc's own middleware.

Impact

With this combination — the combination vinext's own docs recommend for nitro-based deployments — every request in dev returns 500. The app is completely unusable for local development.

Possible fixes

  1. In @vitejs/plugin-rsc configureServer/configurePreviewServer, detect non-runnable environments and fall back to environment.fetchModule() (mirroring the vite.isRunnableDevEnvironment check already present elsewhere in the same file).
  2. In vinext, pass serverHandler: false to the auto-registered rsc() plugin when a nitro plugin is detected, and replace it with vinext's own fetchModule-based handler.

Option 2 keeps the fix scoped to this integration and doesn't require a plugin-rsc release.

Workaround

Downgrading vinext to ^0.0.28 (which pulls @vitejs/plugin-rsc@^0.5.19, a version without this direct .runner.import call in its middleware) restores dev.

Originally created by @jlucaso1 on GitHub (Apr 16, 2026). Original GitHub issue: https://github.com/cloudflare/vinext/issues/853 ## Summary When `vinext` is used together with `nitro/vite` (as shown in vinext's own setup for deployment), every request to the dev server returns a 500 with: ``` [vite] Internal server error: Cannot read properties of undefined (reading 'import') at …/@vitejs/plugin-rsc/dist/plugin-DMfc_Eqq.js:784:76 ``` ## Versions - `vinext@0.0.41` - `@vitejs/plugin-rsc@0.5.24` - `vite@8.0.8` - `nitro` → `nitro-nightly@3.0.1-20260311-140511-1d05f55f` - Node `v22.22.1`, pnpm `10.28.2` ## Reproduction Minimal `vite.config.ts`: ```ts import vinext from 'vinext'; import tailwindcss from '@tailwindcss/vite'; import { defineConfig } from 'vite'; import { nitro } from 'nitro/vite'; export default defineConfig({ plugins: [tailwindcss(), vinext(), nitro({ noExternals: ['tslib'] })], }); ``` App with a Next.js App Router layout. `pnpm dev` → any request to `/` fails. ## Logs ``` 1:50:19 PM [vite] Internal server error: Cannot read properties of undefined (reading 'import') at file:///…/@vitejs+plugin-rsc@0.5.24_…/node_modules/@vitejs/plugin-rsc/dist/plugin-DMfc_Eqq.js:784:76 GET / 500 in 3ms GET /warehouse-requests 500 in 2ms GET /payment-requests?priority=urgent 500 in 2ms GET /payment-receipts 500 in 3ms GET /kanban 500 in 2ms ``` The same error repeats for every route. ## Root cause (as far as I can trace) `@vitejs/plugin-rsc@0.5.24` registers a `configureServer` middleware that does: ```js // @vitejs/plugin-rsc/dist/plugin-DMfc_Eqq.js around L784 const environment = server.environments[options.environmentName]; // "rsc" const resolved = await environment.pluginContainer.resolveId(source); const fetchHandler = getFetchHandlerExport( await environment.runner.import(resolved.id) // ← crashes here ); ``` This path assumes `environment` is a `RunnableDevEnvironment`. When `nitro/vite` is in the plugin chain, nitro's env factory (`createFetchableDevEnvironment` in `nitro-nightly/dist/vite.mjs`) replaces some environments with a `FetchableDevEnvironment` subclass that does **not** have a `.runner` — it exposes `fetchModule()` / `devServer.fetch` instead. So `environment.runner` is `undefined` and the next property access (`.import`) throws. Elsewhere in plugin-rsc (in the `import.meta.viteRsc.import` path), the code *does* guard with `vite.isRunnableDevEnvironment(environment)` before accessing `.runner`. The `configureServer` middleware and `configurePreviewServer` paths don't have that guard. Interestingly, vinext itself already documents this exact situation in `vinext/dist/server/dev-module-runner.js` (comment preserved from source): > When `@cloudflare/vite-plugin` is present it registers its own Vite environments (e.g. `"rsc"`, `"ssr"`) that are *not* `RunnableDevEnvironment` instances. Calling `ssrLoadModule()` in that context crashes… …and provides a `fetchModule()`-based workaround, but that workaround isn't wired into plugin-rsc's own middleware. ## Impact With this combination — the combination vinext's own docs recommend for nitro-based deployments — **every request in dev returns 500**. The app is completely unusable for local development. ## Possible fixes 1. In `@vitejs/plugin-rsc` `configureServer`/`configurePreviewServer`, detect non-runnable environments and fall back to `environment.fetchModule()` (mirroring the `vite.isRunnableDevEnvironment` check already present elsewhere in the same file). 2. In vinext, pass `serverHandler: false` to the auto-registered `rsc()` plugin when a nitro plugin is detected, and replace it with vinext's own `fetchModule`-based handler. Option 2 keeps the fix scoped to this integration and doesn't require a plugin-rsc release. ## Workaround Downgrading `vinext` to `^0.0.28` (which pulls `@vitejs/plugin-rsc@^0.5.19`, a version without this direct `.runner.import` call in its middleware) restores dev.
Author
Owner

@james-elicx commented on GitHub (Apr 17, 2026):

From what you've written, it sounds like this might be a bug in the RSC plugin - have you tried raising an issue there?

<!-- gh-comment-id:4266561870 --> @james-elicx commented on GitHub (Apr 17, 2026): From what you've written, it sounds like this might be a bug in the RSC plugin - have you tried raising an issue there?
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#186
No description provided.