dotnet/aspnetcore · error · Error
Blazor WebAssembly has not initialized.
Error message
Blazor WebAssembly has not initialized.
What it means
Thrown by updateWebAssemblyRootComponents when startPromise exists but Blazor._internal.updateRootComponents is not yet defined. This means the WebAssembly runtime started loading but the .NET-side updateRootComponents handler has not been registered yet (the runtime is mid-initialization, before callEntryPoint wires up _internal).
Solutions
- Let the framework schedule updates via scheduleAfterStarted (await startPromise and the afterStarted callbacks) rather than calling updateRootComponents directly.
- Ensure your code runs inside an afterStarted callback so _internal.updateRootComponents is guaranteed registered.
- If invoking manually, await Blazor.start() fully before issuing updates.
- Check for blocking JS initializers that delay callEntryPoint.
Example fix
// before — calling before runtime registered the callback
Blazor._internal.updateRootComponents(ops, state); // _internal.updateRootComponents is undefined
// after — wait until afterStarted has run
Blazor.start().then(() => {
// _internal.updateRootComponents is now registered
Blazor._internal.updateRootComponents(ops, state);
}); Defensive patterns
Strategy: validation
Validate before calling
// Only invoke updateRootComponents once the callback is registered.
function safeUpdateRootComponents(ops, state) {
if (typeof Blazor._internal.updateRootComponents !== 'function') return;
Blazor._internal.updateRootComponents(ops, state);
} Type guard
function isUpdateRootComponentsReady() {
return typeof Blazor._internal?.updateRootComponents === 'function';
} Try / catch
try {
Blazor._internal.updateRootComponents(ops, state);
} catch (e) {
if (/has not initialized/.test(e.message)) {
// schedule via afterStarted instead
} else throw e;
} Prevention
- Run update logic inside an afterStarted callback.
- Await Blazor.start() fully before issuing updates.
- Avoid blocking JS initializers that delay callEntryPoint.
- Type-check Blazor._internal.updateRootComponents before calling.
When it happens
Trigger: Invoking updateWebAssemblyRootComponents during the window between startWebAssembly() resolving startPromise's existence and platform.start()/callEntryPoint() completing — i.e. the runtime is up enough to call but _internal.updateRootComponents is still unregistered.
Common situations: Enhanced navigation or hot-reload firing very early in startup; manual calls to the API during boot; a slow initializer blocking callEntryPoint; partial initialization where platform load succeeded but managed code has not registered its callbacks.
Related errors
- Blazor WebAssembly has not started.
- Blazor has already started.
- Blazor WebAssembly has already started.
- Descriptors must be assigned a renderer ID before getting…
- Dynamic root components have not been enabled in this…
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/99728fbe2221b09b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Components/Web.JS/src/Boot.WebAssembly.Common.ts:250
})();
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.');
}
Blazor._internal.updateRootComponents(operations, webAssemblyState);
}View on GitHub (pinned to 3600ca084e)