dotnet/runtime · critical · Error

Native module already loaded

Error message

Native module already loaded

What it means

Thrown at the very top of the .NET ES6 runtime prelude when `_nativeModuleLoaded` is already true. The prelude is meant to run exactly once to bind `createDotnetRuntime`/`Module`; a second execution indicates the runtime script was loaded twice, which would double-bind globals and corrupt state.

Solutions

  1. Load the .NET runtime module exactly once; cache the promise if you dynamic-import it.
  2. Audit bundler output for duplicate inclusion of `dotnet.*.js`.
  3. Remove duplicate `<script>` tags referencing the runtime.
  4. If you need isolated runtime instances, load each in its own Worker/iframe.

Example fix

// before: dynamic import twice
await import('dotnet/runtime');
await import('dotnet/runtime'); // throws 'Native module already loaded'

// after: memoise the import
let _rtPromise;
function loadRuntime () { return _rtPromise ??= import('dotnet/runtime'); }
await loadRuntime();
await loadRuntime(); // reuses the same module
Defensive patterns

Strategy: validation

Validate before calling

let _runtimePromise;
function loadRuntimeOnce () {
  if (!_runtimePromise) _runtimePromise = import('dotnet/runtime');
  return _runtimePromise;
}

Type guard

function isNativeModuleFresh (): boolean {
  return !(globalThis as any)._nativeModuleLoaded;
}

Prevention

When it happens

Trigger: Loading the ES6 `dotnet.runtime.js` (or its prelude) twice on the same global scope — e.g. two `<script type="module">` tags pointing at it, or a bundler that includes it twice. The guard at dotnet.es6.pre.js:1 fires on the second load.

Common situations: Duplicate script tags; bundler (webpack/rollup) configuration that ships the runtime in two chunks; dynamically importing the runtime module twice without memoisation; misconfigured splitChunks.

Related errors


AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10). Data as JSON: /api/errors/e6d2ef54684debbe. Report an issue: GitHub.

Appendix: source

Thrown at src/mono/browser/runtime/es6/dotnet.es6.pre.js:1

if (_nativeModuleLoaded) throw new Error("Native module already loaded");
_nativeModuleLoaded = true;
createDotnetRuntime = Module = moduleArg(Module);

View on GitHub (pinned to 60108ba66e)