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
- Ensure Blazor WebAssembly has started (await Blazor.start()) before code that may trigger root-component updates.
- Gate the call on hasStartedLoadingWebAssemblyPlatform() / hasLoadedWebAssemblyPlatform().
- Confirm the page actually uses WebAssembly interactivity before invoking WebAssembly-specific APIs.
- 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
- Only call WebAssembly root-component APIs in pages that actually use WebAssembly.
- Await Blazor.start() before issuing updates.
- Use the framework's started-state accessors as gates.
- Keep WebAssembly-specific code out of Server-only paths.
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
- Blazor WebAssembly has not initialized.
- Blazor has already started.
- Blazor WebAssembly has already started.
- Dynamic root components have not been enabled in this…
- WebAssembly options have already been configured.
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)