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}, DOTNET: ${_ems_.DOTNET.gitHash}

What it means

The native module compares the loader's runtimeBuildInfo.gitHash against _ems_.DOTNET.gitHash baked into the runtime/WASM build. A mismatch means the JS loader and the native/runtime binaries were built from different source revisions, which would silently break the native↔JS ABI, so initialization refuses to continue.

Source

Thrown at src/native/libs/System.Native.Browser/native/index.ts:25

import { _ems_ } from "../../Common/JavaScript/ems-ambient";
import GitHash from "consts:gitHash";

export { SystemJS_RandomBytes } from "./crypto";
export { SystemJS_GetLocaleInfo } from "./globalization-locale";
export { SystemJS_RejectMainPromise, SystemJS_ResolveMainPromise, SystemJS_MarkAsyncMain, SystemJS_ConsoleClear } from "./main";
export { SystemJS_ScheduleTimer, SystemJS_ScheduleBackgroundJob, SystemJS_ScheduleFinalization, SystemJS_ScheduleDiagnosticServer } from "./scheduling";
export { ds_rt_websocket_close, ds_rt_websocket_create, ds_rt_websocket_poll, ds_rt_websocket_recv, ds_rt_websocket_send, ds_rt_browser_performance_measure } from "./diagnostics";


export const gitHash = GitHash;
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 !== _ems_.DOTNET.gitHash) {
        throw new Error(`Mismatched git hashes between loader and runtime. Loader: ${runtimeApi.runtimeBuildInfo.gitHash}, DOTNET: ${_ems_.DOTNET.gitHash}`);
    }

    internals[InternalExchangeIndex.NativeBrowserExportsTable] = nativeBrowserExportsToTable({
        getWasmMemory,
        getWasmTable,
        SystemJS_ScheduleDiagnosticServer: _ems_._SystemJS_ScheduleDiagnosticServer,
        SystemJS_GetMethodName: (pMethodDesc: number) => _ems_._SystemJS_GetMethodName(pMethodDesc),
    });
    _ems_.dotnetUpdateInternals(internals, _ems_.dotnetUpdateInternalsSubscriber);

    setupEmscripten();

    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    function nativeBrowserExportsToTable(map: NativeBrowserExports): NativeBrowserExportsTable {
        // keep in sync with nativeBrowserExportsFromTable()
        return [
            map.getWasmMemory,
            map.getWasmTable,

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. Do a clean rebuild + republish so every dotnet.* artifact (loader, native, wasm, runtime) is from the same commit/SDK.
  2. Hard-refresh the browser, purge the CDN, and unregister any service worker to drop cached bundles.
  3. Pin all dotnet files to the exact same version string in one versioned folder so caches can't mix them.

Example fix

// before: mixed CDN/runtime versions
<script src="https://cdn/7.0.0/dotnet.js"></script>
<!-- bootconfig referencing 8.0.0 runtime/wasm -->

// after: all artifacts from the same 8.0.x build
<script src="https://cdn/8.0.x/dotnet.js"></script>
Defensive patterns

Strategy: validation

Validate before calling

const loaderHash = runtimeApi.runtimeBuildInfo?.gitHash;
if (loaderHash && loaderHash !== _ems_.DOTNET.gitHash) {
  throw new Error("Refusing init: loader/runtime git hash mismatch — republish with a matching build");
}

Try / catch

try { dotnetInitializeModule(internals); }
catch (e) {
  if (/Mismatched git hashes/.test(e.message)) location.reload(true); // after cache purge
  else throw e;
}

Prevention

When it happens

Trigger: Loading a dotnet.native.js/loader from one commit together with a dotnet.wasm/runtime (DOTNET) from a different commit, so the two git hashes disagree.

Common situations: Partial deploy; CDN/browser cache serving a mix of old and new dotnet files; local dev with uncommitted cross-repo builds; hand-editing bootconfig to point at mismatched runtime versions.

Related errors


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