dotnet/runtime · critical · Error
Expected internals to have RuntimeAPI
Error message
Expected internals to have RuntimeAPI
What it means
Thrown by dotnetInitializeModule (diagnostics module) when internals[RuntimeAPI] is not an object. The diagnostics module needs the RuntimeAPI slot to read config, register diagnostics exports, and attach to git-hash/build info; its absence means the internals array was not fully populated.
Source
Thrown at src/native/libs/System.Native.Browser/diagnostics/index.ts:23
import { InternalExchangeIndex } from "../types";
import GitHash from "consts:gitHash";
import { dotnetApi, dotnetUpdateInternals, dotnetUpdateInternalsSubscriber } from "./cross-module";
import { registerExit } from "./exit";
import { installNativeSymbols, symbolicateStackTrace } from "./symbolicate";
import { installLoggingProxy } from "./console-proxy";
import { collectMetrics } from "./dotnet-counters";
import { collectGcDump } from "./dotnet-gcdump";
import { collectCpuSamples } from "./dotnet-cpu-profiler";
import { connectDSRouter, ds_rt_websocket_close, ds_rt_websocket_create, ds_rt_websocket_poll, ds_rt_websocket_recv, ds_rt_websocket_send, initializeDS } from "./diagnostic-server";
import { ds_rt_browser_performance_measure } from "./browser-profiler";
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}, Diagnostics: ${GitHash}`);
}
internals[InternalExchangeIndex.DiagnosticsExportsTable] = diagnosticsExportsToTable({
symbolicateStackTrace,
installNativeSymbols,
ds_rt_websocket_create,
ds_rt_websocket_send,
ds_rt_websocket_poll,
ds_rt_websocket_recv,
ds_rt_websocket_close,
ds_rt_browser_performance_measure,
});
dotnetUpdateInternals(internals, dotnetUpdateInternalsSubscriber);
registerExit();View on GitHub (pinned to 290d5ab72c)
Solutions
- Let the loader sequence module initialization so RuntimeAPI is populated before the diagnostics module initializes.
- Keep loader, runtime, and diagnostics module at the same build version so the InternalExchangeIndex slots line up.
Defensive patterns
Strategy: type-guard
Validate before calling
// Ensure the RuntimeAPI slot is populated before diagnostics init
const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI];
if (typeof runtimeApi !== 'object' || runtimeApi === null) {
throw new Error('RuntimeAPI missing from internals; initialize the runtime before the diagnostics module.');
} Type guard
function hasRuntimeApi(internals: unknown): internals is InternalExchange {
return Array.isArray(internals)
&& typeof internals[InternalExchangeIndex.RuntimeAPI] === 'object'
&& internals[InternalExchangeIndex.RuntimeAPI] !== null;
} Prevention
- Let the loader sequence module init so RuntimeAPI is set first.
- Pin loader/runtime/diagnostics to one build so InternalExchangeIndex slots align.
- In dev, assert the RuntimeAPI slot is present before diagnostics init.
When it happens
Trigger: Diagnostics init runs before the runtime has placed its RuntimeAPI object into the internals exchange, or internals has fewer slots than expected.
Common situations: Init ordering broken (diagnostics initialized before runtime slot populated); version mismatch reducing the internals array length; partial/aborted loader init.
Related errors
- Expected internals to be an array
- Expected internals to be an array
- Expected internals to have RuntimeAPI
- Expected internals to be an array
- Expected internals to have RuntimeAPI
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/65bcf32c929a67d8.
Report an issue: GitHub.