{"record":{"id":"fa9045b98534142b","repo":"dotnet/aspnetcore","slug":"blazor-has-already-started-fa9045","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.WebAssembly.ts","lineNumber":21,"sourceCode":"\n/* eslint-disable array-element-newline */\nimport { Blazor } from './GlobalExports';\nimport { shouldAutoStart } from './BootCommon';\nimport { WebAssemblyStartOptions } from './Platform/WebAssemblyStartOptions';\nimport { setWebAssemblyOptions, startWebAssembly } from './Boot.WebAssembly.Common';\nimport { WebAssemblyComponentDescriptor, discoverComponents, discoverWebAssemblyOptions } from './Services/ComponentDescriptorDiscovery';\nimport { DotNet } from '@microsoft/dotnet-js-interop';\nimport { InitialRootComponentsList } from './Services/InitialRootComponentsList';\nimport { JSEventRegistry } from './Services/JSEventRegistry';\nimport { printErr } from './Platform/Mono/MonoPlatform';\n\ntype BlazorWebAssemblyStartOptions = Partial<WebAssemblyStartOptions> & { webAssembly?: Partial<WebAssemblyStartOptions> };\n\nlet started = false;\n\nasync function boot(options?: BlazorWebAssemblyStartOptions): Promise<void> {\n  if (started) {\n    throw new Error('Blazor has already started.');\n  }\n  started = true;\n\n  // Accept the `webAssembly` property from the blazor.web.js options format\n  const normalizedOptions = options?.webAssembly ?? options ?? {};\n  setWebAssemblyOptions(Promise.resolve(normalizedOptions));\n\n  JSEventRegistry.create(Blazor);\n  const webAssemblyComponents = discoverComponents(document, 'webassembly') as WebAssemblyComponentDescriptor[];\n  const webAssemblyOptions = discoverWebAssemblyOptions(document);\n\n  const components = new InitialRootComponentsList(webAssemblyComponents);\n  await startWebAssembly(components, webAssemblyOptions);\n}\n\nBlazor.start = boot;\nwindow['DotNet'] = DotNet;\n","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Web.JS/src/Boot.WebAssembly.ts#L3-L39","documentation":"Thrown by boot() in Boot.WebAssembly.ts when the module-level 'started' flag is already true. This is the top-level entrypoint guard for the standalone Blazor WebAssembly boot path; re-entry would re-discover components, re-set options, and re-run startWebAssembly.","triggerScenarios":"Calling Blazor.start() in a WebAssembly app more than once per page, or having the boot module evaluated twice.","commonSituations":"Autostart plus a manual Blazor.start(); a retry/recovery routine that re-invokes boot after a partially successful start; HMR or bundler duplication evaluating Boot.WebAssembly.ts twice; a host page that includes blazor.webassembly.js more than once.","solutions":["Call Blazor.start() at most once per page; remove duplicate calls.","Disable autostart and start manually from a single location when you need control.","Memoize the boot promise so retries reuse the first invocation.","Audit bundler/HMR and the host HTML for double-inclusion of the boot script."],"exampleFix":"// before\nfunction safeRestart() { Blazor.start(); } // each call throws\n\n// after\nlet p;\nfunction safeRestart() { return p ?? (p = Blazor.start()); }","handlingStrategy":"validation","validationCode":"// Guard WebAssembly boot at the call site.\nlet wasmStarted;\nfunction startWasmOnce(opts) {\n  if (wasmStarted) return wasmStarted;\n  wasmStarted = Blazor.start(opts);\n  return wasmStarted;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await Blazor.start(opts);\n} catch (e) {\n  if (/already started/.test(e.message)) return;\n  throw e;\n}","preventionTips":["Disable autostart when calling Blazor.start() manually.","Memoize the boot promise at a single entrypoint.","Include the boot script exactly once in index.html.","Prefer page reload over re-boot for recovery from partial failures."],"tags":["blazor-webassembly","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"}