dotnet/runtime · error · Error
No fetch implementation available
Error message
No fetch implementation available
What it means
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.
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.
Example fix
// before: Node 16, no fetch const runtime = await dotnet.create(); // throws // after import fetch from 'node-fetch'; (globalThis as any).fetch = fetch; const runtime = await dotnet.create();
Defensive patterns
Strategy: validation
Validate before calling
function hasFetch(): boolean {
return typeof (globalThis as any).fetch === 'function'
|| typeof (globalThis as any).read === 'function';
}
if (!hasFetch()) {
// install node-fetch or upgrade Node
} Type guard
function hasFetchImpl(): boolean {
return typeof (globalThis as any).fetch === 'function';
} Try / catch
try { await dotnet.create(); } catch (e) {
if (/No fetch implementation/.test((e as Error).message)) {
const fetch = (await import('node-fetch')).default;
(globalThis as any).fetch = fetch;
await dotnet.create();
} else throw e;
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Please install `node-fetch` and `node-abort-controller` npm…
- No fetch implementation available
- NotImplementedException
- Please install `node-fetch` and `node-abort-controller` npm…
- Using node without crypto support. To enable current…
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/1cbfc6518d5e2e6a.
Report an issue: GitHub.
Appendix: source
Thrown at src/native/libs/Common/JavaScript/loader/polyfills.ts:136
const isText = expectedContentType && (expectedContentType.startsWith("application/json") || expectedContentType.startsWith("text/plain"));
const arrayBuffer = read(url, isText ? "utf8" : "binary");
return responseLike(url, arrayBuffer, {
status: 200,
statusText: "OK",
headers: {
"Content-Length": isText ? arrayBuffer.length : arrayBuffer.byteLength.toString(),
"Content-Type": expectedContentType || "application/octet-stream"
}
});
}
} catch (e: any) {
return responseLike(url, null, {
status: 500,
statusText: "ERR28: " + e,
headers: {},
});
}
throw new Error("No fetch implementation available");
}
export function responseLike(url: string, body: ArrayBuffer | string | null, options: ResponseInit): Response {
if (typeof globalThis.Response === "function") {
const response = new Response(body, options);
// Best-effort alignment with the fallback object shape:
// only define `url` if it does not already exist on the response.
if (typeof (response as any).url === "undefined") {
try {
Object.defineProperty(response, "url", { value: url });
} catch {
// Ignore if the implementation does not allow redefining `url`
}
}
return response;
}View on GitHub (pinned to 60108ba66e)