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

  1. Await Blazor.start() (or the returned serverStartPromise) before invoking any circuit-management API.
  2. Guard with hasStartedServer() before calling startCircuit().
  3. 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

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


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/a67942530197054a. Report an issue: GitHub.