{"record":{"id":"a67942530197054a","repo":"dotnet/aspnetcore","slug":"cannot-start-the-circuit-until-blazor-server-has-s","errorCode":null,"errorMessage":"Cannot start the circuit until Blazor Server has started.","messagePattern":"Cannot start the circuit until Blazor Server has started\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/Boot.Server.Common.ts","lineNumber":135,"sourceCode":"  }\n\n  const cleanup = () => {\n    circuit.sendDisconnectBeacon();\n  };\n\n  Blazor.disconnect = cleanup;\n\n  window.addEventListener('pagehide', cleanup, { capture: false, once: true });\n\n  logger.log(LogLevel.Information, 'Blazor server-side application started.');\n\n  jsInitializer.invokeAfterStartedCallbacks(Blazor);\n  resolve();\n}\n\nexport async function startCircuit(): Promise<boolean> {\n  if (!serverStartPromise) {\n    throw new Error('Cannot start the circuit until Blazor Server has started.');\n  }\n\n  if (circuit && !circuit.isDisposedOrDisposing()) {\n    return true;\n  }\n\n  // We might be starting a circuit already, if that's the case, we can just wait for that\n  // to finish.\n  if (circuitStarting) {\n    return await circuitStarting;\n  }\n\n  await serverStartPromise;\n\n  if (circuit && circuit.didRenderingFail()) {\n    // We can't start a new circuit after a rendering failure because the renderer\n    // might be in an invalid state.\n    return false;","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Web.JS/src/Boot.Server.Common.ts#L117-L153","documentation":"Thrown by startCircuit in Boot.Server.Common when serverStartPromise is undefined — i.e. startServer has never been called in this page. A SignalR circuit can only be established after the Server boot path has resolved its initializers and configuration, so attempting to start a circuit before that is rejected rather than silently waiting forever.","triggerScenarios":"Calling Blazor.reconnect() or otherwise triggering startCircuit before Blazor.start()/startServer has run. Also seen when autostart is disabled and application code initiates a reconnect too early.","commonSituations":"Disabling autostart and then calling reconnect before start; HMR swapping out the boot module state so serverStartPromise is reset; race where a network-drop handler fires before initial boot completes.","solutions":["Ensure Blazor.start() has resolved before invoking any reconnect/circuit API; await the start promise.","If autostart is disabled, sequence your code so start runs first and reconnect logic only afterwards.","Check the framework's started state (or guard with your own flag) before calling reconnect.","Investigate HMR/module re-evaluation that may have cleared serverStartPromise."],"exampleFix":"// before\nBlazor._internal.forceReconnect(); // fires startCircuit before boot\n\n// after\nawait Blazor.start();\n// ... later, after a disconnect event\nBlazor.reconnect();","handlingStrategy":"validation","validationCode":"// Ensure start has run before reconnecting the circuit.\nasync function safeReconnect() {\n  await Blazor.start();\n  return Blazor.reconnect();\n}","typeGuard":null,"tryCatchPattern":"try {\n  Blazor.reconnect();\n} catch (e) {\n  if (/Cannot start the circuit until Blazor Server has started/.test(e.message)) {\n    await Blazor.start();\n    Blazor.reconnect();\n  } else throw e;\n}","preventionTips":["Always await Blazor.start() before any reconnect API.","Disable autostart only when you can guarantee ordered start-then-reconnect.","Watch HMR resets of the boot module state.","Tie reconnect logic to the disconnect event, not to application init."],"tags":["blazor-server","circuit","boot","lifecycle"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}