{"record":{"id":"43546a78b03dda57","repo":"dotnet/aspnetcore","slug":"blazor-server-has-already-started","errorCode":null,"errorMessage":"Blazor Server has already started.","messagePattern":"Blazor Server has already started\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/Boot.Server.Common.ts","lineNumber":40,"sourceCode":"let serverStartPromise: Promise<void>;\nlet circuitStarting: Promise<boolean> | undefined;\n\nexport function setCircuitOptions(initializersReady: Promise<Partial<CircuitStartOptions>>) {\n  if (options) {\n    throw new Error('Circuit options have already been configured.');\n  }\n\n  initializersPromise = setOptions(initializersReady);\n\n  async function setOptions(initializers: Promise<Partial<CircuitStartOptions>>): Promise<void> {\n    const configuredOptions = await initializers;\n    options = resolveOptions(configuredOptions);\n  }\n}\n\nexport function startServer(components: RootComponentManager<ServerComponentDescriptor>, jsEventRegistry: JSEventRegistry): Promise<void> {\n  if (serverStartPromise !== undefined) {\n    throw new Error('Blazor Server has already started.');\n  }\n\n  serverStartPromise = new Promise(startServerCore.bind(null, components, jsEventRegistry));\n\n  return serverStartPromise;\n}\n\nasync function startServerCore(components: RootComponentManager<ServerComponentDescriptor>, jsEventRegistry: JSEventRegistry, resolve: () => void, _: any) {\n  await initializersPromise;\n  const jsInitializer = await fetchAndInvokeInitializers(options);\n\n  appState = discoverServerPersistedState(document) || '';\n  logger = new ConsoleLogger(options.logLevel);\n  circuit = new CircuitManager(components, appState, options, logger, jsEventRegistry);\n\n  addDispatchEventMiddleware((_browserRendererId, eventHandlerId, continuation) => {\n    logger.log(LogLevel.Debug, `Dispatching event with handler id ${eventHandlerId}.`);\n    continuation();","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Web.JS/src/Boot.Server.Common.ts#L22-L58","documentation":"Thrown by startServer when the module-level serverStartPromise is already defined. startServer is the single entry point that constructs the SignalR circuit; calling it a second time indicates the Server platform was asked to boot twice.","triggerScenarios":"Invoking Blazor.start() twice on a Server-rendered app, or two boot paths both calling startServer (e.g. an initializer that re-boots, or a navigation handler that re-runs boot).","commonSituations":"Auto-start enabled plus a manual Blazor.start() call; HMR re-running the boot module; misrouted SPA navigation that re-mounts the Blazor script; mixing blazor.server.js with a wrapper that also boots.","solutions":["Guard the call site with hasStartedServer() (Boot.Server.Common.ts:178) before starting.","Disable autostart if you start manually (omit the autostart script tag or set the relevant config flag).","Audit JS initializers and afterStarted callbacks to ensure none re-invoke start.","Ensure the blazor.server.js bundle is loaded exactly once per page load."],"exampleFix":"// before\nBlazor.start();\n// ... later ...\nBlazor.start(); // throws: already started\n\n// after\nimport { hasStartedServer } from './Boot.Server.Common';\nif (!hasStartedServer()) {\n  Blazor.start();\n}","handlingStrategy":"validation","validationCode":"import { hasStartedServer } from './Boot.Server.Common';\n\nfunction startServerOnce(components: any, events: any) {\n  if (hasStartedServer()) return Promise.resolve();\n  return startServer(components, events);\n}","typeGuard":"import { hasStartedServer } from './Boot.Server.Common';\n\nfunction serverIsStarted(): boolean {\n  return hasStartedServer();\n}","tryCatchPattern":"try {\n  await Blazor.start();\n} catch (e) {\n  if (/already started/.test((e as Error).message)) {\n    // benign: already running\n  } else throw e;\n}","preventionTips":["Guard with hasStartedServer() before calling startServer or Blazor.start().","Disable autostart when booting manually.","Audit afterStarted callbacks so none re-invoke boot.","Load blazor.server.js once per page."],"tags":["blazor-server","startup","circuit","singleton"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}