{"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/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Web.JS/src/Boot.Server.Common.ts#L117-L153","documentation":"Thrown by startCircuit when serverStartPromise is undefined. startCircuit can only create/recreate a SignalR circuit after the Server platform has been initialized via startServer; calling it before that has no logger, no options, and no circuit infrastructure to use.","triggerScenarios":"An external caller (reconnection handler, interop, or test harness) invoking startCircuit() before Blazor.start() has resolved, or before startServer has been called at all.","commonSituations":"Custom reconnection logic that races the boot sequence; calling Blazor.reconnect()/resume APIs too early; tests that exercise circuit management without booting the Server platform first.","solutions":["Await Blazor.start() (or the returned serverStartPromise) before invoking any circuit-management API.","Guard with hasStartedServer() before calling startCircuit().","Defer reconnection logic to afterStartedCallbacks so boot ordering is guaranteed."],"exampleFix":"// before: circuit start races boot\nstartCircuit(); // serverStartPromise undefined -> throws\nBlazor.start();\n\n// after: boot first, then manage the circuit\nawait Blazor.start();\nawait startCircuit();","handlingStrategy":"validation","validationCode":"import { hasStartedServer, startCircuit } from './Boot.Server.Common';\n\nasync function startCircuitIfReady() {\n  if (!hasStartedServer()) {\n    throw new Error('Wait for Blazor.start() before managing the circuit.');\n  }\n  return startCircuit();\n}","typeGuard":"import { hasStartedServer } from './Boot.Server.Common';\n\nfunction canStartCircuit(): boolean {\n  return hasStartedServer();\n}","tryCatchPattern":"try {\n  await startCircuit();\n} catch (e) {\n  if (/until Blazor Server has started/.test((e as Error).message)) {\n    await Blazor.start();\n    await startCircuit();\n  } else throw e;\n}","preventionTips":["Await Blazor.start() before any circuit-management API.","Move reconnection logic into afterStartedCallbacks.","Guard circuit calls with hasStartedServer().","In tests, boot the Server platform before exercising circuit APIs."],"tags":["blazor-server","startup","circuit","ordering"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}