dotnet/aspnetcore · error · Error

WebAssembly options have already been configured.

Error message

WebAssembly options have already been configured.

What it means

Thrown by setWebAssemblyOptions in Boot.WebAssembly.Common when the module-level 'options' is already set. The WebAssembly options resolution is meant to run once per boot; calling it again would overwrite resolved WebAssemblyStartOptions and desynchronize initializer handling.

Solutions

  1. Boot WebAssembly exactly once per page; remove the duplicate call.
  2. Disable autostart and start manually from a single location.
  3. Memoize the start promise so re-entry is idempotent.
  4. Confirm the boot script is included only once in the host HTML.

Example fix

// before
<script autostart src="_framework/blazor.webassembly.js"></script>
<button onclick="Blazor.start()">Restart</button> // throws

// after
<script src="_framework/blazor.webassembly.js" autostart="false"></script>
<button onclick="bootOnce()">Start</button>
<script>let p; function bootOnce(){ return p ?? (p = Blazor.start()); }</script>
Defensive patterns

Strategy: validation

Validate before calling

// Memoize WebAssembly boot so options are configured once.
let wasmPromise;
function bootWasmOnce(opts) {
  return wasmPromise ?? (wasmPromise = Blazor.start(opts));
}

Try / catch

try {
  await Blazor.start(opts);
} catch (e) {
  if (/already been configured|already started/.test(e.message)) return;
  throw e;
}

Prevention

When it happens

Trigger: The WebAssembly boot path (Boot.WebAssembly.ts) being entered twice in the same page, or setWebAssemblyOptions invoked manually after the framework already configured options.

Common situations: Autostart plus a manual Blazor.start() in WebAssembly mode; a host page that includes blazor.webassembly.js twice; HMR re-running the boot module; micro-frontend setups that mount multiple WebAssembly apps through one boot path.

Related errors


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

Appendix: source

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

  firstUpdate = false;
}

let resolveInitializersPromise: (value: void) => void;
const initializersPromise = new Promise<void>(resolve => {
  resolveInitializersPromise = resolve;
});

export function isFirstUpdate() {
  return firstUpdate;
}

export function setWaitForRootComponents(): void {
  waitForRootComponents = true;
}

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));

View on GitHub (pinned to 3600ca084e)