dotnet/aspnetcore · error · Error

Blazor WebAssembly has not started.

Error message

Blazor WebAssembly has not started.

What it means

Thrown by updateWebAssemblyRootComponents when the module-level startPromise is undefined, i.e. startWebAssembly was never called. Root-component updates only make sense once the WebAssembly platform has begun booting, because they are forwarded to Blazor._internal.updateRootComponents which is wired up inside startCore.

Source

Thrown at src/Components/Web.JS/src/Boot.WebAssembly.Common.ts:246

    await monoPlatform.load(finalOptions, resolveBootConfigPromise, justDownload);
    if (!justDownload) {
      loadedWebAssemblyPlatform = true;
    }
  })();
  return platformLoadPromise;
}

export function hasStartedLoadingWebAssemblyPlatform(): boolean {
  return platformLoadPromise !== undefined;
}

export function hasLoadedWebAssemblyPlatform(): boolean {
  return loadedWebAssemblyPlatform;
}

export function updateWebAssemblyRootComponents(operations: string, webAssemblyState: string): void {
  if (!startPromise) {
    throw new Error('Blazor WebAssembly has not started.');
  }

  if (!Blazor._internal.updateRootComponents) {
    throw new Error('Blazor WebAssembly has not initialized.');
  }

  if (!started) {
    scheduleAfterStarted(operations, webAssemblyState);
  } else {
    Blazor._internal.updateRootComponents(operations, webAssemblyState);
  }
}

async function scheduleAfterStarted(operations: string, webAssemblyState: string): Promise<void> {
  await startPromise;

  if (!Blazor._internal.updateRootComponents) {
    throw new Error('Blazor WebAssembly has not initialized.');

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Await Blazor.start() before issuing any root-component update.
  2. Guard with hasStartedWebAssembly() before calling updateWebAssemblyRootComponents.
  3. Defer the update logic to an afterStarted callback so ordering is guaranteed.

Example fix

// before: update before start
Blazor._internal.updateRootComponents(ops, state); // throws
await Blazor.start();

// after
await Blazor.start();
Blazor._internal.updateRootComponents(ops, state);
Defensive patterns

Strategy: validation

Validate before calling

import { hasStartedWebAssembly } from './Boot.WebAssembly.Common';

function updateRootComponentsSafe(ops: string, state: string) {
  if (!hasStartedWebAssembly()) {
    throw new Error('Start WebAssembly before updating root components.');
  }
  updateWebAssemblyRootComponents(ops, state);
}

Type guard

import { hasStartedWebAssembly } from './Boot.WebAssembly.Common';

function canUpdateRoots(): boolean {
  return hasStartedWebAssembly();
}

Try / catch

try {
  Blazor._internal.updateRootComponents(ops, state);
} catch (e) {
  if (/WebAssembly has not started/.test((e as Error).message)) {
    await Blazor.start();
    Blazor._internal.updateRootComponents(ops, state);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling Blazor._internal.updateRootComponents (or a higher-level API that routes to updateWebAssemblyRootComponents) before Blazor.start() has been invoked on the WebAssembly bundle.

Common situations: Custom code or an initializer that pushes root-component updates before boot; interactive WebAssembly render mode triggered before the bundle finished starting; tests exercising root-component plumbing without booting WebAssembly first.

Related errors


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