{"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/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Web.JS/src/Boot.WebView.ts#L2-L38","documentation":"Thrown by boot() in Boot.WebView.ts (the .NET MAUI / WebView Blazor entry) when its module-level 'started' flag is already true. The WebView boot attaches the IPC dispatcher, starts the IPC receiver, and wires navigation — all single-shot operations for the lifetime of the WebView.","triggerScenarios":"Calling Blazor.start() a second time inside a BlazorWebView, or the WebView reloading and re-evaluating the boot bundle while a prior boot's flag persists in the same JS context (e.g. via a non-isolated script scope).","commonSituations":"A native reload that does not reset the JS context; manually invoking Blazor.start() in addition to the auto-start the WebView performs; an embedded page that includes the script twice; testing harnesses that re-run boot without a fresh WebView.","solutions":["Let the BlazorWebView start Blazor itself; do not call Blazor.start() manually unless you have disabled autostart.","Ensure the WebView performs a full navigation (fresh JS context) rather than re-evaluating scripts in place.","Guard the call with a window-level flag before invoking."],"exampleFix":"// before\n<script src=\"_framework/blazor.webview.js\" autostart></script>\n<script>Blazor.start();</script> <!-- throws -->\n\n// after: rely on autostart, or\n<script src=\"_framework/blazor.webview.js\"></script>\n<script>Blazor.start();</script>","handlingStrategy":"validation","validationCode":"function startWebViewBlazorOnce() {\n  if ((window as any).__blazorWebViewStarted) return Promise.resolve();\n  (window as any).__blazorWebViewStarted = true;\n  return Blazor.start();\n}","typeGuard":"function webViewBlazorStarted(): boolean {\n  return !!(window as any).__blazorWebViewStarted;\n}","tryCatchPattern":"try {\n  await Blazor.start();\n} catch (e) {\n  if (/already started/.test((e as Error).message)) return;\n  throw e;\n}","preventionTips":["Let the BlazorWebView start Blazor itself; do not call Blazor.start() unless autostart is off.","Use full navigations to reset the JS context rather than re-evaluating scripts.","Guard any manual start with a window flag.","Avoid embedding the boot script twice in WebView HTML."],"tags":["blazor-webview","startup","singleton","autostart","maui"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}