vitejs/vite · error · TypeError

FetchableDevEnvironment `dispatchFetch` must receive a…

Error message

FetchableDevEnvironment `dispatchFetch` must receive a `Request` object.

What it means

Thrown by FetchableDevEnvironment.dispatchFetch() when the argument is not an instance of the global Request class. dispatchFetch forwards the request straight to the stored handleRequest, so a non-Request value would break the handler's contract and the Fetch API semantics the environment is built around.

Solutions

  1. Wrap the input in a Request before dispatching: dispatchFetch(new Request(url, { method, headers, body })).
  2. If adapting a Node IncomingMessage, use new Request(url, { method: req.method, headers: req.headers, body: req }).
  3. Verify there is only one Request global in the process — multiple fetch polyfills can break instanceof checks.

Example fix

// before
env.dispatchFetch(req.url)
// after
env.dispatchFetch(new Request(req.url, { method: req.method, headers: req.headers, body: req }))
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(request instanceof Request)) {
  request = new Request(typeof request === 'string' ? request : request.url, request as any)
}
await env.dispatchFetch(request)

Type guard

function isRequest(v: unknown): v is Request {
  return typeof Request !== 'undefined' && v instanceof Request
}

Prevention

When it happens

Trigger: Calling environment.dispatchFetch(urlString) with a plain string URL, an options object, a Node.js IncomingMessage, or any value that is not `instanceof Request`. The instanceof check is at fetchableEnvironments.ts:49.

Common situations: Adapting an Express/Node http.Server request to the fetchable environment by passing req.url or the req object directly instead of constructing a Request. Polyfilling fetch in an older Node version where the global Request differs between modules (dual Request classes fail instanceof).

Related errors


AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11). Data as JSON: /api/errors/440bcb7bcac8c6f4. Report an issue: GitHub.

Appendix: source

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

): environment is FetchableDevEnvironment {
  return environment instanceof FetchableDevEnvironment
}

class FetchableDevEnvironment extends DevEnvironment {
  private _handleRequest: (request: Request) => Promise<Response> | Response

  constructor(
    name: string,
    config: ResolvedConfig,
    context: FetchableDevEnvironmentContext,
  ) {
    super(name, config, context)
    this._handleRequest = context.handleRequest
  }

  public async dispatchFetch(request: Request): Promise<Response> {
    if (!(request instanceof Request)) {
      throw new TypeError(
        'FetchableDevEnvironment `dispatchFetch` must receive a `Request` object.',
      )
    }
    const response = await this._handleRequest(request)
    if (!(response instanceof Response)) {
      throw new TypeError(
        'FetchableDevEnvironment `context.handleRequest` must return a `Response` object.',
      )
    }
    return response
  }
}

export type { FetchableDevEnvironment }

View on GitHub (pinned to b4d66fee14)