vitejs/vite · error · TypeError

FetchableDevEnvironment requires a global `Request` and `Res

Error message

FetchableDevEnvironment requires a global `Request` and `Response` object.

What it means

createFetchableDevEnvironment at packages/vite/src/node/server/environments/fetchableEnvironments.ts:16 requires global Request and Response (the Fetch API). On runtimes where either is undefined (old Node < 18, stripped globals, non-browser non-Node engines) it throws a TypeError before constructing anything.

Source

Thrown at packages/vite/src/node/server/environments/fetchableEnvironments.ts:16

import type { ResolvedConfig } from '../../config'
import type { DevEnvironmentContext } from '../environment'
import { DevEnvironment } from '../environment'
import type { Environment } from '../../environment'

export interface FetchableDevEnvironmentContext extends DevEnvironmentContext {
  handleRequest(request: Request): Promise<Response> | Response
}

export function createFetchableDevEnvironment(
  name: string,
  config: ResolvedConfig,
  context: FetchableDevEnvironmentContext,
): FetchableDevEnvironment {
  if (typeof Request === 'undefined' || typeof Response === 'undefined') {
    throw new TypeError(
      'FetchableDevEnvironment requires a global `Request` and `Response` object.',
    )
  }

  if (!context.handleRequest) {
    throw new TypeError(
      'FetchableDevEnvironment requires a `handleRequest` method during initialisation.',
    )
  }

  return new FetchableDevEnvironment(name, config, context)
}

export function isFetchableDevEnvironment(
  environment: Environment,
): environment is FetchableDevEnvironment {
  return environment instanceof FetchableDevEnvironment
}

View on GitHub (pinned to 89620f09af)

Solutions

  1. Run on Node 18+ (global Request/Response ship there) or polyfill whatwg-fetch / undici before constructing the environment.
  2. If you only need a plain DevEnvironment, use new DevEnvironment / the regular createServer path instead of the Fetchable variant.
  3. Set globalThis.Request / globalThis.Response from your polyfill of choice before calling createFetchableDevEnvironment.

Example fix

// before (Node 16, no globals)
import { createFetchableDevEnvironment } from 'vite'
const env = createFetchableDevEnvironment('ssr', config, ctx)

// after
import { Request, Response } from 'undici'
globalThis.Request ??= Request
globalThis.Response ??= Response
const env = createFetchableDevEnvironment('ssr', config, ctx)
Defensive patterns

Strategy: type-guard

Validate before calling

function assertFetchGlobals() {
  if (typeof Request === 'undefined' || typeof Response === 'undefined') {
    throw new Error('FetchableDevEnvironment needs Node >= 18 or a whatwg-fetch polyfill')
  }
}
assertFetchGlobals()

Type guard

function hasFetchGlobals(): boolean {
  return typeof Request !== 'undefined' && typeof Response !== 'undefined'
}

Prevention

When it happens

Trigger: Constructing a FetchableDevEnvironment on Node < 18 (no global fetch); in a sandbox that deleted globalThis.Request/Response; in a JS engine without Fetch API polyfills; running under Jest with testEnvironment=node and no fetch polyfill.

Common situations: CI on an older Node image; embedded JS runtimes; test setups that do not provide whatwg fetch; SSR adapters targeting edge runtimes but developed on Node 16.

Related errors


AI-assisted analysis of vitejs/vite@89620f09af (2026-08-03). Data as JSON: /data/errors/e23dcd51e35c08ff.json. Report an issue: GitHub.