{"record":{"id":"660c05aff97dbf63","repo":"dotnet/runtime","slug":"expected-internals-to-have-runtimeapi-660c05","errorCode":null,"errorMessage":"Expected internals to have RuntimeAPI","messagePattern":"Expected internals to have RuntimeAPI","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/native/libs/System.Native.Browser/utils/index.ts","lineNumber":28,"sourceCode":"    setHeapB32, setHeapB8, setHeapU8, setHeapU16, setHeapU32, setHeapI8, setHeapI16, setHeapI32, setHeapI52, setHeapU52, setHeapI64Big, setHeapF32, setHeapF64,\n    getHeapB32, getHeapB8, getHeapU8, getHeapU16, getHeapU32, getHeapI8, getHeapI16, getHeapI32, getHeapI52, getHeapU52, getHeapI64Big, getHeapF32, getHeapF64,\n    localHeapViewI8, localHeapViewI16, localHeapViewI32, localHeapViewI64Big, localHeapViewU8, localHeapViewU16, localHeapViewU32, localHeapViewF32, localHeapViewF64,\n    zeroRegion,\n    arrayBufferNeedsCopy,\n    viewOrCopy,\n} from \"./memory\";\nimport { stringsInit, stringToUTF16, stringToUTF16Ptr, stringToUTF8, stringToUTF8Ptr, utf16ToString, utf8ToStringRelaxed } from \"./strings\";\nimport { abortPosix, getExitStatus } from \"./host\";\nimport { dotnetUpdateInternals, dotnetUpdateInternalsSubscriber } from \"../utils/cross-module\";\nimport { initPolyfills } from \"../utils/polyfills\";\nimport { registerRuntime } from \"./runtime-list\";\nimport { registerCDAC } from \"./cdac\";\nimport { abortBackgroundTimers, runBackgroundTimers } from \"./scheduling\";\n\nexport function dotnetInitializeModule(internals: InternalExchange): void {\n    if (!Array.isArray(internals)) throw new Error(\"Expected internals to be an array\");\n    const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI];\n    if (typeof runtimeApi !== \"object\") throw new Error(\"Expected internals to have RuntimeAPI\");\n\n    if (runtimeApi.runtimeBuildInfo.gitHash && runtimeApi.runtimeBuildInfo.gitHash !== GitHash) {\n        throw new Error(`Mismatched git hashes between loader and runtime. Loader: ${runtimeApi.runtimeBuildInfo.gitHash}, BrowserUtils: ${GitHash}`);\n    }\n\n    initPolyfills();\n    stringsInit();\n    registerRuntime(runtimeApi);\n    registerCDAC(runtimeApi);\n\n    if (!Array.isArray(internals)) throw new Error(\"Expected internals to be an array\");\n    const runtimeApiLocal: Partial<RuntimeAPI> = {\n        setHeapB32, setHeapB8, setHeapU8, setHeapU16, setHeapU32, setHeapI8, setHeapI16, setHeapI32, setHeapI52, setHeapU52, setHeapI64Big, setHeapF32, setHeapF64,\n        getHeapB32, getHeapB8, getHeapU8, getHeapU16, getHeapU32, getHeapI8, getHeapI16, getHeapI32, getHeapI52, getHeapU52, getHeapI64Big, getHeapF32, getHeapF64,\n        localHeapViewI8, localHeapViewI16, localHeapViewI32, localHeapViewI64Big, localHeapViewU8, localHeapViewU16, localHeapViewU32, localHeapViewF32, localHeapViewF64,\n    };\n    Object.assign(runtimeApi, runtimeApiLocal);\n","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/native/libs/System.Native.Browser/utils/index.ts#L10-L46","documentation":"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.","triggerScenarios":"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.","commonSituations":"BrowserUtils initializing before the core runtime; a version mismatch shifting InternalExchangeIndex values; partial cache serving an old utils bundle with a new runtime.","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)."],"exampleFix":"// before: utils init runs before runtime fills the slot\n// internals[0] === undefined\ndotnetInitializeModule(internals);\n\n// after\nawait loadCoreRuntimeFirst(); // populates internals[0]\ndotnetInitializeModule(internals);","handlingStrategy":"type-guard","validationCode":"if (!Array.isArray(internals) || typeof internals[0] !== \"object\")\n  throw new Error(\"RuntimeAPI missing — load core runtime before BrowserUtils\");\ndotnetInitializeModule(internals);","typeGuard":"const hasRuntimeApi = (x: any[]): x is any[] =>\n  Array.isArray(x) && typeof x[0] === \"object\" && x[0] !== null;","tryCatchPattern":null,"preventionTips":["Initialize BrowserUtils only after the core runtime fills internals[0].","Keep the utils bundle and runtime from the same build."],"tags":["initialization","runtime-interop","internals"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}