{"record":{"id":"440bcb7bcac8c6f4","repo":"vitejs/vite","slug":"fetchabledevenvironment-dispatchfetch-must-recei","errorCode":null,"errorMessage":"FetchableDevEnvironment `dispatchFetch` must receive a `Request` object.","messagePattern":"FetchableDevEnvironment `dispatchFetch` must receive a `Request` object\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/server/environments/fetchableEnvironments.ts","lineNumber":50,"sourceCode":"): environment is FetchableDevEnvironment {\n  return environment instanceof FetchableDevEnvironment\n}\n\nclass FetchableDevEnvironment extends DevEnvironment {\n  private _handleRequest: (request: Request) => Promise<Response> | Response\n\n  constructor(\n    name: string,\n    config: ResolvedConfig,\n    context: FetchableDevEnvironmentContext,\n  ) {\n    super(name, config, context)\n    this._handleRequest = context.handleRequest\n  }\n\n  public async dispatchFetch(request: Request): Promise<Response> {\n    if (!(request instanceof Request)) {\n      throw new TypeError(\n        'FetchableDevEnvironment `dispatchFetch` must receive a `Request` object.',\n      )\n    }\n    const response = await this._handleRequest(request)\n    if (!(response instanceof Response)) {\n      throw new TypeError(\n        'FetchableDevEnvironment `context.handleRequest` must return a `Response` object.',\n      )\n    }\n    return response\n  }\n}\n\nexport type { FetchableDevEnvironment }\n","sourceCodeStart":32,"sourceCodeEnd":65,"githubUrl":"https://github.com/vitejs/vite/blob/b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab/packages/vite/src/node/server/environments/fetchableEnvironments.ts#L32-L65","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Wrap the input in a Request before dispatching: dispatchFetch(new Request(url, { method, headers, body })).","If adapting a Node IncomingMessage, use new Request(url, { method: req.method, headers: req.headers, body: req }).","Verify there is only one Request global in the process — multiple fetch polyfills can break instanceof checks."],"exampleFix":"// before\nenv.dispatchFetch(req.url)\n// after\nenv.dispatchFetch(new Request(req.url, { method: req.method, headers: req.headers, body: req }))","handlingStrategy":"type-guard","validationCode":"if (!(request instanceof Request)) {\n  request = new Request(typeof request === 'string' ? request : request.url, request as any)\n}\nawait env.dispatchFetch(request)","typeGuard":"function isRequest(v: unknown): v is Request {\n  return typeof Request !== 'undefined' && v instanceof Request\n}","tryCatchPattern":null,"preventionTips":["Always construct a Request at your adapter boundary before dispatching.","Keep a single global fetch polyfill to avoid instanceof mismatches across Realms."],"tags":["fetchable-environment","fetch-api","type-mismatch"],"backgroundTag":null,"analyzedSha":"b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab","analyzedAt":"2026-08-11T11:49:19.515Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}