dotnet/runtime · critical · Error
Mismatched git hashes between loader and runtime. Loader
Error message
Mismatched git hashes between loader and runtime. Loader: ${runtimeApi.runtimeBuildInfo.gitHash}, BrowserUtils: ${GitHash} What it means
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.
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.
Example fix
// before: utils bundle cached from old deploy // after: hard reload / cache-bust _framework/* // then verify both report the same hash in the diagnostics output
Defensive patterns
Strategy: validation
Validate before calling
import GitHash from "consts:gitHash";
function assertUtilsHashMatches(runtimeApi: any) {
const loader = runtimeApi?.runtimeBuildInfo?.gitHash;
if (loader && loader !== GitHash) {
throw new Error(`Utils build mismatch: loader=${loader}, utils=${GitHash}`);
}
} Type guard
null
Try / catch
null
Prevention
- 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.
When it happens
Trigger: Loading a BrowserUtils JS bundle whose baked GitHash differs from the loader's runtimeBuildInfo.gitHash; both are non-empty.
Common situations: 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.
Related errors
- Mismatched git hashes between loader and runtime. Loader
- Mismatched git hashes between loader and runtime. Loader
- Mismatched git hashes between loader and runtime. Loader
- Mismatched git hashes between loader and runtime. Loader
- Unsupported Webcil version
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/5e239455083c0aad.
Report an issue: GitHub.
Appendix: source
Thrown at src/native/libs/System.Native.Browser/utils/index.ts:31
zeroRegion,
arrayBufferNeedsCopy,
viewOrCopy,
} from "./memory";
import { stringsInit, stringToUTF16, stringToUTF16Ptr, stringToUTF8, stringToUTF8Ptr, utf16ToString, utf8ToStringRelaxed } from "./strings";
import { abortPosix, getExitStatus } from "./host";
import { dotnetUpdateInternals, dotnetUpdateInternalsSubscriber } from "../utils/cross-module";
import { initPolyfills } from "../utils/polyfills";
import { registerRuntime } from "./runtime-list";
import { registerCDAC } from "./cdac";
import { abortBackgroundTimers, runBackgroundTimers } from "./scheduling";
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}, BrowserUtils: ${GitHash}`);
}
initPolyfills();
stringsInit();
registerRuntime(runtimeApi);
registerCDAC(runtimeApi);
if (!Array.isArray(internals)) throw new Error("Expected internals to be an array");
const runtimeApiLocal: Partial<RuntimeAPI> = {
setHeapB32, setHeapB8, setHeapU8, setHeapU16, setHeapU32, setHeapI8, setHeapI16, setHeapI32, setHeapI52, setHeapU52, setHeapI64Big, setHeapF32, setHeapF64,
getHeapB32, getHeapB8, getHeapU8, getHeapU16, getHeapU32, getHeapI8, getHeapI16, getHeapI32, getHeapI52, getHeapU52, getHeapI64Big, getHeapF32, getHeapF64,
localHeapViewI8, localHeapViewI16, localHeapViewI32, localHeapViewI64Big, localHeapViewU8, localHeapViewU16, localHeapViewU32, localHeapViewF32, localHeapViewF64,
};
Object.assign(runtimeApi, runtimeApiLocal);
internals[InternalExchangeIndex.BrowserUtilsExportsTable] = browserUtilsExportsToTable({
utf16ToString,
stringToUTF16,View on GitHub (pinned to 60108ba66e)