vitejs/vite · error · TypeError
FetchableDevEnvironment requires a global `Request` and…
Error message
FetchableDevEnvironment requires a global `Request` and `Response` object.
What it means
createFetchableDevEnvironment requires the global Request and Response constructors (the Fetch standard) so that its dispatchFetch/handleRequest contract can work. If either global is undefined it throws a TypeError immediately. Fetchable environments expose HTTP-style request/response handling, which is impossible without those globals.
Solutions
- Run on Node 18+ (or a runtime) where Request and Response are global.
- Polyfill the globals before creating the environment: install undici / whatwg-fetch and assign globalThis.Request/Response.
- If you do not need the fetchable contract, use the regular DevEnvironment instead.
- Ensure any polyfill module is imported before the Vite environment code runs.
Example fix
// before — Node < 18 or stripped runtime
createFetchableDevEnvironment('client', config, ctx)
// after — polyfill first
import { Request, Response } from 'undici'
globalThis.Request = globalThis.Request || Request
globalThis.Response = globalThis.Response || Response
createFetchableDevEnvironment('client', config, ctx) Defensive patterns
Strategy: type-guard
Validate before calling
function assertFetchGlobals() {
if (typeof Request === 'undefined' || typeof Response === 'undefined') {
throw new TypeError('Polyfill global Request/Response before creating a fetchable environment')
}
}
assertFetchGlobals() Type guard
function hasFetchGlobals(): boolean {
return typeof Request !== 'undefined' && typeof Response !== 'undefined'
} Prevention
- Run on Node 18+ where Request/Response are global.
- Polyfill fetch globals (e.g. undici) before creating the environment.
- Use the regular DevEnvironment if you do not need the fetchable contract.
When it happens
Trigger: Calling createFetchableDevEnvironment in a runtime without fetch globals — e.g. an old Node version (< 18) where Request/Response are not global, or a stripped-down JS engine. The check runs at the top of the factory before any setup.
Common situations: Running Vite's fetchable environment on Node 16 or below, in a custom embedded runtime, or under a test harness that deletes fetch globals. Also when a polyfill is loaded after the environment is created.
Related errors
- Cannot use "sourcemapInterceptor: 'node'" because…
- currently full bundle mode is only available for client…
- Environment " " is not defined in the config.
- Environment " " is not defined in the config.
- Failed to decode base64-encoded data URL, Buffer and atob…
AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11).
Data as JSON: /api/errors/e23dcd51e35c08ff.
Report an issue: GitHub.
Appendix: 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 b4d66fee14)