dotnet/runtime · error · Error

Failed to invoke 'onRuntimeReady' on library initializer '${

Error message

Failed to invoke 'onRuntimeReady' on library initializer '${name}': ${message}

What it means

callLibraryInitializerOnRuntimeReady awaits module.onRuntimeReady(dotnetApi) inside try/catch and re-throws with context on failure. This runs for modules in resources.modulesAfterConfigLoaded and resources.modulesAfterRuntimeReady after the runtime is fully initialized, passing the RuntimeAPI surface to the hook.

Source

Thrown at src/native/libs/Common/JavaScript/loader/assets.ts:95

            await module.onRuntimeConfigLoaded(loaderConfig);
        }
        return module;
    } catch (err) {
        const message = err instanceof Error ? err.message : String(err);
        throw new Error(`Failed to invoke 'onRuntimeConfigLoaded' on library initializer '${name}': ${message}`, { cause: err });
    }
}

export async function callLibraryInitializerOnRuntimeReady([asset, modulePromise]: [JsAsset, Promise<any>]): Promise<void> {
    const module = await modulePromise;
    const name = asset.name || asset.resolvedUrl || "unknown";
    try {
        if (typeof module.onRuntimeReady === "function") {
            await module.onRuntimeReady(dotnetApi);
        }
    } catch (err) {
        const message = err instanceof Error ? err.message : String(err);
        throw new Error(`Failed to invoke 'onRuntimeReady' on library initializer '${name}': ${message}`, { cause: err });
    }
}

export function fetchMainWasm(asset: WasmAsset): Promise<Response> {
    totalAssetsToDownload++;
    const assetInternal = asset as AssetEntryInternal;
    if (assetInternal.name && !asset.resolvedUrl) {
        asset.resolvedUrl = locateFile(assetInternal.name);
    }
    assetInternal.behavior = "dotnetwasm";
    if (!asset.resolvedUrl) throw new Error("Invalid config, resources is not set");
    mainWasmAsset = asset;
    wasmBinaryPromise = loadResource(assetInternal);
    return wasmBinaryPromise;
}

export async function instantiateMainWasm(imports: WebAssembly.Imports, successCallback: InstantiateWasmSuccessCallback): Promise<void> {
    const assetInternal = mainWasmAsset as AssetEntryInternal;

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. Use the '${name}' placeholder value to locate the failing initializer and inspect its onRuntimeReady implementation.
  2. Upgrade/downgrade the package shipping the initializer to match the dotnet runtime build version.
  3. Type-check the api object before calling methods (typeof api.RUNTIME.methods.x === 'function').
  4. Remove the module from modulesAfterRuntimeReady/modulesAfterConfigLoaded in the boot config to confirm it is the culprit.

Example fix

// before
export function onRuntimeReady(api) {
  api.RUNTIME.methods.bindings.doSomething(); // may be undefined
}

// after
export function onRuntimeReady(api) {
  const fn = api.RUNTIME.methods.bindings?.doSomething;
  if (typeof fn !== 'function') throw new Error('doSomething unavailable in this runtime build');
  fn();
}
Defensive patterns

Strategy: try-catch

Type guard

function hasOnRuntimeReady(m: any): m is { onRuntimeReady: (api: any) => void | Promise<void> } {
  return typeof m?.onRuntimeReady === 'function';
}

Try / catch

try {
  await callLibraryInitializerOnRuntimeReady([asset, modPromise]);
} catch (err) {
  console.error('onRuntimeReady failed for', asset.name, err.cause ?? err);
  // optionally mark the feature as unavailable and continue
}

Prevention

When it happens

Trigger: A library initializer exporting onRuntimeReady(api) throws — e.g. calling an API method that does not exist on this runtime build, or performing side effects (DOM, fetch, native interop) that fail.

Common situations: Version skew between the initializer (from a NuGet package) and the loaded runtime API; an initializer calling dotnetApi.RUNTIME.methods that were stripped; runtime not actually ready due to an upstream partial failure; Node-only initializer running in a browser or vice-versa.

Related errors


AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06). Data as JSON: /api/errors/e6bc42d1f4a35812. Report an issue: GitHub.