dotnet/runtime · critical · Error
Expected internals to be an array
Error message
Expected internals to be an array
What it means
Thrown by dotnetInitializeModule (diagnostics module) when the internals argument is not an array. The loader and runtime exchange state through a positional InternalExchange array; a non-array means the init contract was violated (wrong caller shape or version skew).
Source
Thrown at src/native/libs/System.Native.Browser/diagnostics/index.ts:20
// The .NET Foundation licenses this file to you under the MIT license.
import type { DiagnosticsExportsTable, InternalExchange, DiagnosticsExports } from "./types";
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,
});View on GitHub (pinned to 290d5ab72c)
Solutions
- Use the official loader entry points; do not call dotnetInitializeModule directly.
- Ensure the diagnostics module and the loader/runtime are from the same build so the InternalExchange contract matches.
Defensive patterns
Strategy: type-guard
Validate before calling
// Guard the contract before initializing the diagnostics module
if (!Array.isArray(internals)) {
throw new TypeError('dotnetInitializeModule expects the InternalExchange array from the loader.');
} Type guard
function isInternalExchange(x): x is InternalExchange {
return Array.isArray(x) && x.length > 0;
} Prevention
- Never call dotnetInitializeModule directly; let the loader drive module init.
- Keep loader, runtime, and diagnostics module at the same build so the contract matches.
- Add an Array.isArray assertion in dev builds to catch contract breakage early.
When it happens
Trigger: Calling the diagnostics module's dotnetInitializeModule with an object, undefined, or a malformed value instead of the InternalExchange array produced by the loader.
Common situations: Custom bundler/loader that wraps or replaces internals; version mismatch between loader and diagnostics module; manually invoking the initializer with the wrong argument.
Related errors
- Expected internals to be an array
- Expected internals to have RuntimeAPI
- Mismatched git hashes between loader and runtime. Loader: ${
- 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/c1255e92a5e4bb4d.
Report an issue: GitHub.