Skip to content

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

@jlucaso1

Description

@jlucaso1

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions