dotnet/runtime · critical · Error
Expected internals to have RuntimeAPI
Error message
Expected internals to have RuntimeAPI
What it means
After the array check, the native module reads internals[InternalExchangeIndex.RuntimeAPI] and asserts it is an object. Without the runtime API handle it cannot register the NativeBrowserExportsTable, install Emscripten hooks, or call dotnetUpdateInternals, so initialization is aborted.
Source
Thrown at src/native/libs/System.Native.Browser/native/index.ts:22
import type { InternalExchange, NativeBrowserExports, NativeBrowserExportsTable } from "../types";
import { InternalExchangeIndex } from "../types";
import { _ems_ } from "../../Common/JavaScript/ems-ambient";
import GitHash from "consts:gitHash";
export { SystemJS_RandomBytes } from "./crypto";
export { SystemJS_GetLocaleInfo } from "./globalization-locale";
export { SystemJS_RejectMainPromise, SystemJS_ResolveMainPromise, SystemJS_MarkAsyncMain, SystemJS_ConsoleClear } from "./main";
export { SystemJS_ScheduleTimer, SystemJS_ScheduleBackgroundJob, SystemJS_ScheduleFinalization, SystemJS_ScheduleDiagnosticServer } from "./scheduling";
export { ds_rt_websocket_close, ds_rt_websocket_create, ds_rt_websocket_poll, ds_rt_websocket_recv, ds_rt_websocket_send, ds_rt_browser_performance_measure } from "./diagnostics";
export const gitHash = GitHash;
export function dotnetInitializeModule(internals: InternalExchange): void {
if (!Array.isArray(internals)) throw new Error("Expected internals to be an array");
const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI];
if (typeof runtimeApi !== "object") throw new Error("Expected internals to have RuntimeAPI");
if (runtimeApi.runtimeBuildInfo.gitHash && runtimeApi.runtimeBuildInfo.gitHash !== _ems_.DOTNET.gitHash) {
throw new Error(`Mismatched git hashes between loader and runtime. Loader: ${runtimeApi.runtimeBuildInfo.gitHash}, DOTNET: ${_ems_.DOTNET.gitHash}`);
}
internals[InternalExchangeIndex.NativeBrowserExportsTable] = nativeBrowserExportsToTable({
getWasmMemory,
getWasmTable,
SystemJS_ScheduleDiagnosticServer: _ems_._SystemJS_ScheduleDiagnosticServer,
SystemJS_GetMethodName: (pMethodDesc: number) => _ems_._SystemJS_GetMethodName(pMethodDesc),
});
_ems_.dotnetUpdateInternals(internals, _ems_.dotnetUpdateInternalsSubscriber);
setupEmscripten();
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function nativeBrowserExportsToTable(map: NativeBrowserExports): NativeBrowserExportsTable {
// keep in sync with nativeBrowserExportsFromTable()View on GitHub (pinned to 290d5ab72c)
Solutions
- Load the core dotnet runtime bundle (which populates internals[InternalExchangeIndex.RuntimeAPI]) before initializing the native browser module.
- Rebuild/republish all dotnet artifacts from one SDK/commit so InternalExchangeIndex values line up.
- Purge CDN/browser/service-worker caches of mixed-version bundles.
Example fix
// before: init called before runtime populated the slot
// internals[0] === undefined
dotnetInitializeModule(internals);
// after: ensure runtime API is present
if (typeof internals[0] !== "object") throw new Error("load runtime first");
dotnetInitializeModule(internals); Defensive patterns
Strategy: type-guard
Validate before calling
if (!Array.isArray(internals) || typeof internals[0] !== "object")
throw new Error("RuntimeAPI missing — load core runtime first");
dotnetInitializeModule(internals); Type guard
const hasRuntimeApi = (x: any[]): x is any[] => Array.isArray(x) && typeof x[0] === "object" && x[0] !== null;
Prevention
- Initialize the native browser module only after the core runtime has populated internals[0].
- Keep loader and native bundles from the same build so InternalExchangeIndex values agree.
When it happens
Trigger: internals is a valid array but the RuntimeAPI slot is undefined — wrong array length, the slot not yet populated by the core runtime, or reordered indices caused by a loader/native version mismatch.
Common situations: Native bundle initialized before the core runtime populated RuntimeAPI; a version mismatch that shifts InternalExchangeIndex values; a partial deploy where only some bundles updated.
Related errors
- Expected internals to have RuntimeAPI
- Expected internals to be an array
- Expected internals to be an array
- Expected internals to have RuntimeAPI
- Expected internals to be an array
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/7bd170163b9efbc0.
Report an issue: GitHub.