{"record":{"id":"5e239455083c0aad","repo":"dotnet/runtime","slug":"mismatched-git-hashes-between-loader-and-runtime-5e2394","errorCode":null,"errorMessage":"Mismatched git hashes between loader and runtime. Loader: ${runtimeApi.runtimeBuildInfo.gitHash}, BrowserUtils: ${GitHash}","messagePattern":"Mismatched git hashes between loader and runtime\\. Loader: (.+?), BrowserUtils: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/native/libs/System.Native.Browser/utils/index.ts","lineNumber":31,"sourceCode":"    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\n    internals[InternalExchangeIndex.BrowserUtilsExportsTable] = browserUtilsExportsToTable({\n        utf16ToString,\n        stringToUTF16,","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/native/libs/System.Native.Browser/utils/index.ts#L13-L49","documentation":"The BrowserUtils module (System.Native.Browser/utils) embeds its own git hash via `consts:gitHash`. During initialization it asserts that hash equals runtimeApi.runtimeBuildInfo.gitHash from the loader. A mismatch means the utils support bundle and the runtime/loader were built from different commits.","triggerScenarios":"Loading a BrowserUtils JS bundle whose baked GitHash differs from the loader's runtimeBuildInfo.gitHash; both are non-empty.","commonSituations":"Same class of deployment drift as the other git-hash checks: mixed SDK/workload versions in wwwroot, stale CDN/browser cache, partial publish, dev rebuild of only the runtime project.","solutions":["Redeploy the full set of dotnet support JS + wasm from one build so BrowserUtils and the loader agree on the hash.","Clear caches (browser, CDN, service worker) that could serve a stale utils bundle.","Clean and rebuild the whole solution to ensure a single hash is stamped.","Audit the wwwroot/_framework directory to confirm no leftover files from a previous SDK version."],"exampleFix":"// before: utils bundle cached from old deploy\n\n// after: hard reload / cache-bust _framework/*\n// then verify both report the same hash in the diagnostics output","handlingStrategy":"validation","validationCode":"import GitHash from \"consts:gitHash\";\n\nfunction assertUtilsHashMatches(runtimeApi: any) {\n  const loader = runtimeApi?.runtimeBuildInfo?.gitHash;\n  if (loader && loader !== GitHash) {\n    throw new Error(`Utils build mismatch: loader=${loader}, utils=${GitHash}`);\n  }\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Publish the complete set of dotnet support JS + wasm from one build.","Clear browser/CDN/service-worker caches that may serve a stale utils bundle.","Clean and rebuild so a single hash is stamped.","Audit wwwroot/_framework for leftover files from prior SDK versions."],"tags":["git-hash","build-integrity","utils","version-mismatch"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}