{"record":{"id":"e6d2ef54684debbe","repo":"dotnet/runtime","slug":"native-module-already-loaded","errorCode":null,"errorMessage":"Native module already loaded","messagePattern":"Native module already loaded","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/mono/browser/runtime/es6/dotnet.es6.pre.js","lineNumber":1,"sourceCode":"if (_nativeModuleLoaded) throw new Error(\"Native module already loaded\");\n_nativeModuleLoaded = true;\ncreateDotnetRuntime = Module = moduleArg(Module);\n","sourceCodeStart":1,"sourceCodeEnd":4,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/mono/browser/runtime/es6/dotnet.es6.pre.js#L1-L4","documentation":"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.","triggerScenarios":"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.","commonSituations":"Duplicate script tags; bundler (webpack/rollup) configuration that ships the runtime in two chunks; dynamically importing the runtime module twice without memoisation; misconfigured splitChunks.","solutions":["Load the .NET runtime module exactly once; cache the promise if you dynamic-import it.","Audit bundler output for duplicate inclusion of `dotnet.*.js`.","Remove duplicate `<script>` tags referencing the runtime.","If you need isolated runtime instances, load each in its own Worker/iframe."],"exampleFix":"// before: dynamic import twice\nawait import('dotnet/runtime');\nawait import('dotnet/runtime'); // throws 'Native module already loaded'\n\n// after: memoise the import\nlet _rtPromise;\nfunction loadRuntime () { return _rtPromise ??= import('dotnet/runtime'); }\nawait loadRuntime();\nawait loadRuntime(); // reuses the same module","handlingStrategy":"validation","validationCode":"let _runtimePromise;\nfunction loadRuntimeOnce () {\n  if (!_runtimePromise) _runtimePromise = import('dotnet/runtime');\n  return _runtimePromise;\n}","typeGuard":"function isNativeModuleFresh (): boolean {\n  return !(globalThis as any)._nativeModuleLoaded;\n}","tryCatchPattern":null,"preventionTips":["Load the runtime module exactly once; memoise dynamic imports.","Audit bundler output (webpack/rollup) for duplicate runtime chunks.","Remove duplicate `<script>` tags referencing `dotnet.*.js`.","Use a separate Worker/iframe per isolated runtime instance."],"tags":["runtime","lifecycle","singleton","bundler","es6-module"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}