dotnet/aspnetcore · error · Error
Cannot start the circuit until Blazor Server has started.
Error message
Cannot start the circuit until Blazor Server has started.
What it means
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.
Source
Thrown at src/Components/Web.JS/src/Boot.Server.Common.ts:135
}
const cleanup = () => {
circuit.sendDisconnectBeacon();
};
Blazor.disconnect = cleanup;
window.addEventListener('pagehide', cleanup, { capture: false, once: true });
logger.log(LogLevel.Information, 'Blazor server-side application started.');
jsInitializer.invokeAfterStartedCallbacks(Blazor);
resolve();
}
export async function startCircuit(): Promise<boolean> {
if (!serverStartPromise) {
throw new Error('Cannot start the circuit until Blazor Server has started.');
}
if (circuit && !circuit.isDisposedOrDisposing()) {
return true;
}
// We might be starting a circuit already, if that's the case, we can just wait for that
// to finish.
if (circuitStarting) {
return await circuitStarting;
}
await serverStartPromise;
if (circuit && circuit.didRenderingFail()) {
// We can't start a new circuit after a rendering failure because the renderer
// might be in an invalid state.
return false;View on GitHub (pinned to 294cab2f9b)
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.
Example fix
// before: circuit start races boot startCircuit(); // serverStartPromise undefined -> throws Blazor.start(); // after: boot first, then manage the circuit await Blazor.start(); await startCircuit();
Defensive patterns
Strategy: validation
Validate before calling
import { hasStartedServer, startCircuit } from './Boot.Server.Common';
async function startCircuitIfReady() {
if (!hasStartedServer()) {
throw new Error('Wait for Blazor.start() before managing the circuit.');
}
return startCircuit();
} Type guard
import { hasStartedServer } from './Boot.Server.Common';
function canStartCircuit(): boolean {
return hasStartedServer();
} Try / catch
try {
await startCircuit();
} catch (e) {
if (/until Blazor Server has started/.test((e as Error).message)) {
await Blazor.start();
await startCircuit();
} else throw e;
} Prevention
- 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.
When it happens
Trigger: An external caller (reconnection handler, interop, or test harness) invoking startCircuit() before Blazor.start() has resolved, or before startServer has been called at all.
Common situations: 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.
Related errors
- Blazor Server has already started.
- Circuit options have already been configured.
- Blazor has already started.
- Blazor WebAssembly has not started.
- Cannot start a disposed circuit.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/a67942530197054a.
Report an issue: GitHub.