{"record":{"id":"e345705e58a80dc5","repo":"dotnet/aspnetcore","slug":"blazor-has-already-started-e34570","errorCode":null,"errorMessage":"Blazor has already started.","messagePattern":"Blazor has already started\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/Boot.WebView.ts","lineNumber":20,"sourceCode":"// The .NET Foundation licenses this file to you under the MIT license.\n\nimport { DotNet } from '@microsoft/dotnet-js-interop';\nimport { Blazor } from './GlobalExports';\nimport { shouldAutoStart } from './BootCommon';\nimport { internalFunctions as navigationManagerFunctions } from './Services/NavigationManager';\nimport { startIpcReceiver } from './Platform/WebView/WebViewIpcReceiver';\nimport { sendAttachPage, sendBeginInvokeDotNetFromJS, sendEndInvokeJSFromDotNet, sendByteArray, sendLocationChanged, sendLocationChanging } from './Platform/WebView/WebViewIpcSender';\nimport { fetchAndInvokeInitializers } from './JSInitializers/JSInitializers.WebView';\nimport { receiveDotNetDataStream } from './StreamingInterop';\nimport { WebRendererId } from './Rendering/WebRendererId';\n\nlet started = false;\n\nexport let dispatcher: DotNet.ICallDispatcher;\n\nasync function boot(): Promise<void> {\n  if (started) {\n    throw new Error('Blazor has already started.');\n  }\n  started = true;\n\n  dispatcher = DotNet.attachDispatcher({\n    beginInvokeDotNetFromJS: sendBeginInvokeDotNetFromJS,\n    endInvokeJSFromDotNet: sendEndInvokeJSFromDotNet,\n    sendByteArray: sendByteArray,\n  });\n\n  const jsInitializer = await fetchAndInvokeInitializers();\n\n  startIpcReceiver();\n\n  Blazor._internal.receiveWebViewDotNetDataStream = receiveWebViewDotNetDataStream;\n\n  navigationManagerFunctions.enableNavigationInterception(WebRendererId.WebView);\n  navigationManagerFunctions.listenForNavigationEvents(WebRendererId.WebView, sendLocationChanged, sendLocationChanging);\n","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Web.JS/src/Boot.WebView.ts#L2-L38","documentation":"Thrown by boot() in Boot.WebView.ts when the module-level 'started' flag is already true. This guards the Blazor WebView boot path (used inside native shells via IPC), which must attach the DotNet dispatcher, start the IPC receiver, and run initializers exactly once per WebView instance.","triggerScenarios":"Calling the WebView boot path twice in the same WebView, or framework re-entry (e.g. native host triggering re-initialization while a boot is in flight or completed).","commonSituations":"Native shell code that re-initializes the WebView without reloading it; misconfigured WebView lifecycle hooks re-running boot on resume; HMR-style reload inside the WebView; bundler duplication evaluating Boot.WebView.ts twice.","solutions":["Initialize Blazor in the WebView exactly once; reload the WebView (full navigation) if you truly need a fresh Blazor instance.","Guard any native-initiated boot calls with a flag set on first completion.","Avoid calling Blazor.start() from multiple native lifecycle events.","Inspect the WebView bootstrap script inclusion for duplication."],"exampleFix":"// before — native handler re-boots on resume\nvoid OnResume() { webView.CoreWebView2.ExecuteScriptAsync(\"Blazor.start()\"); }\n\n// after — only boot once per WebView navigation\nbool booted;\nvoid OnResume() {\n  if (!booted) { webView.CoreWebView2.ExecuteScriptAsync(\"Blazor.start()\"); booted = true; }\n}","handlingStrategy":"validation","validationCode":"// Boot Blazor in the WebView exactly once per navigation.\nlet webViewBooted;\nfunction bootWebViewOnce() {\n  if (webViewBooted) return;\n  webViewBooted = true;\n  Blazor.start();\n}","typeGuard":null,"tryCatchPattern":"try {\n  await Blazor.start();\n} catch (e) {\n  if (/already started/.test(e.message)) return;\n  throw e;\n}","preventionTips":["Reload the WebView (full navigation) when you need a fresh Blazor instance.","Drive boot from a single native lifecycle event, not several.","Guard native re-init handlers with a 'booted' flag.","Confirm the bootstrap script is included once in the WebView HTML."],"tags":["blazor-webview","boot","lifecycle","double-start"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}