dotnet/aspnetcore · error · Error

Blazor WebAssembly has not started.

Error message

Blazor WebAssembly has not started.

What it means

Thrown by updateWebAssemblyRootComponents in Boot.WebAssembly.Common when the module-level startPromise is falsy — meaning startWebAssembly has never been called. Updating root components requires an already-booted WebAssembly runtime; calling it before boot would silently drop the update, so the framework throws.

Solutions

  1. Ensure Blazor WebAssembly has started (await Blazor.start()) before code that may trigger root-component updates.
  2. Gate the call on hasStartedLoadingWebAssemblyPlatform() / hasLoadedWebAssemblyPlatform().
  3. Confirm the page actually uses WebAssembly interactivity before invoking WebAssembly-specific APIs.
  4. Avoid calling WebAssembly root-component APIs from code shared with Server-only pages.

Example fix

// before
Blazor._internal.updateRootComponents?.(ops, state); // can fire pre-start

// after — gate on started state
import { hasLoadedWebAssemblyPlatform } from './Boot.WebAssembly.Common';
if (hasLoadedWebAssemblyPlatform()) {
  updateWebAssemblyRootComponents(ops, state);
}
Defensive patterns

Strategy: validation

Validate before calling

// Gate WebAssembly root-component updates on having started.
import { hasStartedLoadingWebAssemblyPlatform } from './Boot.WebAssembly.Common';
function maybeUpdateRootComponents(ops, state) {
  if (!hasStartedLoadingWebAssemblyPlatform()) return;
  updateWebAssemblyRootComponents(ops, state);
}

Try / catch

try {
  updateWebAssemblyRootComponents(ops, state);
} catch (e) {
  if (/has not started/.test(e.message)) {
    // not a WebAssembly context; ignore
  } else throw e;
}

Prevention

When it happens

Trigger: Framework code (e.g. enhanced-navigation or hot-reload handlers) invoking updateWebAssemblyRootComponents before Blazor WebAssembly has started, or in a context where the WebAssembly boot path was never entered (e.g. a Server-only page).

Common situations: A page configured for Server-only interactivity accidentally triggering the WebAssembly root-component update path; calling the API manually before start; routing from a WebAssembly page to a non-WebAssembly context and back during shutdown.

Related errors


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

Appendix: 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 3600ca084e)