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

  1. Use the official loader entry points; do not call dotnetInitializeModule directly.
  2. 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

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


AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06). Data as JSON: /api/errors/c1255e92a5e4bb4d. Report an issue: GitHub.