{"record":{"id":"1cbfc6518d5e2e6a","repo":"dotnet/runtime","slug":"no-fetch-implementation-available-1cbfc6","errorCode":null,"errorMessage":"No fetch implementation available","messagePattern":"No fetch implementation available","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/native/libs/Common/JavaScript/loader/polyfills.ts","lineNumber":136,"sourceCode":"            const isText = expectedContentType && (expectedContentType.startsWith(\"application/json\") || expectedContentType.startsWith(\"text/plain\"));\n            const arrayBuffer = read(url, isText ? \"utf8\" : \"binary\");\n            return responseLike(url, arrayBuffer, {\n                status: 200,\n                statusText: \"OK\",\n                headers: {\n                    \"Content-Length\": isText ? arrayBuffer.length : arrayBuffer.byteLength.toString(),\n                    \"Content-Type\": expectedContentType || \"application/octet-stream\"\n                }\n            });\n        }\n    } catch (e: any) {\n        return responseLike(url, null, {\n            status: 500,\n            statusText: \"ERR28: \" + e,\n            headers: {},\n        });\n    }\n    throw new Error(\"No fetch implementation available\");\n}\n\nexport function responseLike(url: string, body: ArrayBuffer | string | null, options: ResponseInit): Response {\n    if (typeof globalThis.Response === \"function\") {\n        const response = new Response(body, options);\n\n        // Best-effort alignment with the fallback object shape:\n        // only define `url` if it does not already exist on the response.\n        if (typeof (response as any).url === \"undefined\") {\n            try {\n                Object.defineProperty(response, \"url\", { value: url });\n            } catch {\n                // Ignore if the implementation does not allow redefining `url`\n            }\n        }\n\n        return response;\n    }","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/native/libs/Common/JavaScript/loader/polyfills.ts#L118-L154","documentation":"fetchLike() walks three fallbacks: Node fs (only for file://), globalThis.fetch (browser/Node 18+), and a global read() function (shell/emscripten FS). If none apply, it throws 'No fetch implementation available'. This is a hard environment-incompatibility error: the host cannot make HTTP requests at all, so no asset can be downloaded.","triggerScenarios":"Running the loader in a JS runtime with no fetch and no read() (e.g. an old Node <18 without a fetch polyfill, a minimal V8 isolate, or a custom host that exports neither). Node without setting globalThis.fetch and with a non-file:// URL (so the fs branch is skipped).","commonSituations":"Node 16 or earlier without node-fetch installed. Bun/Deno in Node-compat mode that hides globalThis.fetch. A bundled browser build that accidentally executes server-side before window.fetch exists. Tests in jsdom that forgot to install whatwg-fetch.","solutions":["Install and assign globalThis.fetch before bootstrap: import fetch from 'node-fetch'; globalThis.fetch = fetch as any; (Node <18).","Upgrade to Node 18+ which has native global fetch.","If in a shell/emscripten host, ensure the global read() function is exposed.","If you supply a custom loader via loadBootResourceCallback, that bypasses fetchLike entirely — return Response objects from it."],"exampleFix":"// before: Node 16, no fetch\nconst runtime = await dotnet.create(); // throws\n\n// after\nimport fetch from 'node-fetch';\n(globalThis as any).fetch = fetch;\nconst runtime = await dotnet.create();","handlingStrategy":"validation","validationCode":"function hasFetch(): boolean {\n  return typeof (globalThis as any).fetch === 'function'\n      || typeof (globalThis as any).read === 'function';\n}\nif (!hasFetch()) {\n  // install node-fetch or upgrade Node\n}","typeGuard":"function hasFetchImpl(): boolean {\n  return typeof (globalThis as any).fetch === 'function';\n}","tryCatchPattern":"try { await dotnet.create(); } catch (e) {\n  if (/No fetch implementation/.test((e as Error).message)) {\n    const fetch = (await import('node-fetch')).default;\n    (globalThis as any).fetch = fetch;\n    await dotnet.create();\n  } else throw e;\n}","preventionTips":["Require Node 18+ in package.json engines so global fetch is present.","Install node-fetch as a dependency for older Node.","Feature-detect fetch at startup and fail fast with a helpful message.","In custom hosts, expose a global read() function the loader can use."],"tags":["environment","fetch","node","polyfill"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}