dotnet/aspnetcore · error · Error
Blazor WebAssembly has already started.
Error message
Blazor WebAssembly has already started.
What it means
Thrown by startWebAssembly when the module-level startPromise is already defined. startWebAssembly loads the Mono runtime and entry point exactly once; a second call indicates the WebAssembly platform was asked to boot twice.
Source
Thrown at src/Components/Web.JS/src/Boot.WebAssembly.Common.ts:75
}
export function setWebAssemblyOptions(initializersReady: Promise<Partial<WebAssemblyStartOptions>>) {
if (options) {
throw new Error('WebAssembly options have already been configured.');
}
setOptions(initializersReady);
async function setOptions(initializers: Promise<Partial<WebAssemblyStartOptions>>) {
const configuredOptions = await initializers;
options = configuredOptions;
resolveInitializersPromise();
}
}
export function startWebAssembly(components: RootComponentManager<WebAssemblyComponentDescriptor>, options: WebAssemblyServerOptions | undefined): Promise<void> {
if (startPromise !== undefined) {
throw new Error('Blazor WebAssembly has already started.');
}
startPromise = new Promise(startCore.bind(null, components, options));
return startPromise;
}
async function startCore(components: RootComponentManager<WebAssemblyComponentDescriptor>, options: WebAssemblyServerOptions | undefined, resolve, _) {
if (inAuthRedirectIframe()) {
// eslint-disable-next-line @typescript-eslint/no-empty-function
await new Promise(() => { }); // See inAuthRedirectIframe for explanation
}
const platformLoadPromise = loadWebAssemblyPlatformIfNotStarted(options);
addDispatchEventMiddleware((browserRendererId, eventHandlerId, continuation) => {
// It's extremely unusual, but an event can be raised while we're in the middle of synchronously applying a
// renderbatch. For example, a renderbatch might mutate the DOM in such a way as to cause an <input> to loseView on GitHub (pinned to 294cab2f9b)
Solutions
- Guard with hasStartedWebAssembly() (Boot.WebAssembly.Common.ts:200) before starting.
- Pick autostart OR a single manual Blazor.start(); not both.
- Ensure the WebAssembly bundle is loaded once per page/iframe.
Example fix
// before
Blazor.start();
// ... later ...
Blazor.start(); // throws
// after
import { hasStartedWebAssembly } from './Boot.WebAssembly.Common';
if (!hasStartedWebAssembly()) {
await Blazor.start();
} Defensive patterns
Strategy: validation
Validate before calling
import { hasStartedWebAssembly } from './Boot.WebAssembly.Common';
function startWasmOnce(components: any, opts: any) {
if (hasStartedWebAssembly()) return Promise.resolve();
return startWebAssembly(components, opts);
} Type guard
import { hasStartedWebAssembly } from './Boot.WebAssembly.Common';
function wasmStarted(): boolean {
return hasStartedWebAssembly();
} Try / catch
try {
await Blazor.start();
} catch (e) {
if (/already started/.test((e as Error).message)) return;
throw e;
} Prevention
- Guard start with hasStartedWebAssembly().
- Pick autostart OR one manual start.
- Load blazor.webassembly.js once per page/iframe.
- Avoid HMR re-evaluation of the boot module.
When it happens
Trigger: Calling Blazor.start() twice for a WebAssembly app, or two boot paths both invoking startWebAssembly (e.g. Blazor Web App with an InteractiveWebAssembly render mode plus a manual start).
Common situations: Autostart plus manual start; HMR reloading blazor.webassembly.js; tests or hosting shells that re-invoke boot; an iframe re-running the bundle.
Related errors
- Blazor has already started.
- Blazor has already started.
- Blazor has already started.
- WebAssembly options have already been configured.
- Blazor has already started.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/387ebf91bd374f2d.
Report an issue: GitHub.