dotnet/runtime · critical · Error
Expected internals to have RuntimeAPI
Error message
Expected internals to have RuntimeAPI
What it means
The BrowserUtils module reads internals[InternalExchangeIndex.RuntimeAPI] and asserts it is an object before it can install heap view accessors, register the runtime/CDAC, and build the BrowserUtilsExportsTable. Without it, none of the string/memory marshaling the rest of the runtime depends on can be wired up.
Source
Thrown at src/native/libs/System.Native.Browser/utils/index.ts:28
setHeapB32, setHeapB8, setHeapU8, setHeapU16, setHeapU32, setHeapI8, setHeapI16, setHeapI32, setHeapI52, setHeapU52, setHeapI64Big, setHeapF32, setHeapF64,
getHeapB32, getHeapB8, getHeapU8, getHeapU16, getHeapU32, getHeapI8, getHeapI16, getHeapI32, getHeapI52, getHeapU52, getHeapI64Big, getHeapF32, getHeapF64,
localHeapViewI8, localHeapViewI16, localHeapViewI32, localHeapViewI64Big, localHeapViewU8, localHeapViewU16, localHeapViewU32, localHeapViewF32, localHeapViewF64,
zeroRegion,
arrayBufferNeedsCopy,
viewOrCopy,
} from "./memory";
import { stringsInit, stringToUTF16, stringToUTF16Ptr, stringToUTF8, stringToUTF8Ptr, utf16ToString, utf8ToStringRelaxed } from "./strings";
import { abortPosix, getExitStatus } from "./host";
import { dotnetUpdateInternals, dotnetUpdateInternalsSubscriber } from "../utils/cross-module";
import { initPolyfills } from "../utils/polyfills";
import { registerRuntime } from "./runtime-list";
import { registerCDAC } from "./cdac";
import { abortBackgroundTimers, runBackgroundTimers } from "./scheduling";
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 !== GitHash) {
throw new Error(`Mismatched git hashes between loader and runtime. Loader: ${runtimeApi.runtimeBuildInfo.gitHash}, BrowserUtils: ${GitHash}`);
}
initPolyfills();
stringsInit();
registerRuntime(runtimeApi);
registerCDAC(runtimeApi);
if (!Array.isArray(internals)) throw new Error("Expected internals to be an array");
const runtimeApiLocal: Partial<RuntimeAPI> = {
setHeapB32, setHeapB8, setHeapU8, setHeapU16, setHeapU32, setHeapI8, setHeapI16, setHeapI32, setHeapI52, setHeapU52, setHeapI64Big, setHeapF32, setHeapF64,
getHeapB32, getHeapB8, getHeapU8, getHeapU16, getHeapU32, getHeapI8, getHeapI16, getHeapI32, getHeapI52, getHeapU52, getHeapI64Big, getHeapF32, getHeapF64,
localHeapViewI8, localHeapViewI16, localHeapViewI32, localHeapViewI64Big, localHeapViewU8, localHeapViewU16, localHeapViewU32, localHeapViewF32, localHeapViewF64,
};
Object.assign(runtimeApi, runtimeApiLocal);
View on GitHub (pinned to 290d5ab72c)
Solutions
- Ensure the core runtime bundle loads and fills internals[InternalExchangeIndex.RuntimeAPI] before BrowserUtils init.
- Rebuild/republish all dotnet bundles from one SDK so InternalExchangeIndex values align.
- Cache-bust all dotnet artifacts together (versioned folder or hash in URL).
Example fix
// before: utils init runs before runtime fills the slot // internals[0] === undefined dotnetInitializeModule(internals); // after await loadCoreRuntimeFirst(); // populates internals[0] 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 before BrowserUtils");
dotnetInitializeModule(internals); Type guard
const hasRuntimeApi = (x: any[]): x is any[] => Array.isArray(x) && typeof x[0] === "object" && x[0] !== null;
Prevention
- Initialize BrowserUtils only after the core runtime fills internals[0].
- Keep the utils bundle and runtime from the same build.
When it happens
Trigger: internals is a valid array but the RuntimeAPI slot is undefined — the core runtime hasn't populated it yet, or index values are misaligned due to a loader/utils version mismatch.
Common situations: BrowserUtils initializing before the core runtime; a version mismatch shifting InternalExchangeIndex values; partial cache serving an old utils bundle with a new runtime.
Related errors
- Expected internals to have RuntimeAPI
- Expected internals to be an array
- Expected internals to have RuntimeAPI
- Expected internals to be an array
- Expected internals to be an array
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/660c05aff97dbf63.
Report an issue: GitHub.