{"record":{"id":"e6bc42d1f4a35812","repo":"dotnet/runtime","slug":"failed-to-invoke-onruntimeready-on-library-initi","errorCode":null,"errorMessage":"Failed to invoke 'onRuntimeReady' on library initializer '${name}': ${message}","messagePattern":"Failed to invoke 'onRuntimeReady' on library initializer '(.+?)': (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/native/libs/Common/JavaScript/loader/assets.ts","lineNumber":95,"sourceCode":"            await module.onRuntimeConfigLoaded(loaderConfig);\n        }\n        return module;\n    } catch (err) {\n        const message = err instanceof Error ? err.message : String(err);\n        throw new Error(`Failed to invoke 'onRuntimeConfigLoaded' on library initializer '${name}': ${message}`, { cause: err });\n    }\n}\n\nexport async function callLibraryInitializerOnRuntimeReady([asset, modulePromise]: [JsAsset, Promise<any>]): Promise<void> {\n    const module = await modulePromise;\n    const name = asset.name || asset.resolvedUrl || \"unknown\";\n    try {\n        if (typeof module.onRuntimeReady === \"function\") {\n            await module.onRuntimeReady(dotnetApi);\n        }\n    } catch (err) {\n        const message = err instanceof Error ? err.message : String(err);\n        throw new Error(`Failed to invoke 'onRuntimeReady' on library initializer '${name}': ${message}`, { cause: err });\n    }\n}\n\nexport function fetchMainWasm(asset: WasmAsset): Promise<Response> {\n    totalAssetsToDownload++;\n    const assetInternal = asset as AssetEntryInternal;\n    if (assetInternal.name && !asset.resolvedUrl) {\n        asset.resolvedUrl = locateFile(assetInternal.name);\n    }\n    assetInternal.behavior = \"dotnetwasm\";\n    if (!asset.resolvedUrl) throw new Error(\"Invalid config, resources is not set\");\n    mainWasmAsset = asset;\n    wasmBinaryPromise = loadResource(assetInternal);\n    return wasmBinaryPromise;\n}\n\nexport async function instantiateMainWasm(imports: WebAssembly.Imports, successCallback: InstantiateWasmSuccessCallback): Promise<void> {\n    const assetInternal = mainWasmAsset as AssetEntryInternal;","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/native/libs/Common/JavaScript/loader/assets.ts#L77-L113","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use the '${name}' placeholder value to locate the failing initializer and inspect its onRuntimeReady implementation.","Upgrade/downgrade the package shipping the initializer to match the dotnet runtime build version.","Type-check the api object before calling methods (typeof api.RUNTIME.methods.x === 'function').","Remove the module from modulesAfterRuntimeReady/modulesAfterConfigLoaded in the boot config to confirm it is the culprit."],"exampleFix":"// before\nexport function onRuntimeReady(api) {\n  api.RUNTIME.methods.bindings.doSomething(); // may be undefined\n}\n\n// after\nexport function onRuntimeReady(api) {\n  const fn = api.RUNTIME.methods.bindings?.doSomething;\n  if (typeof fn !== 'function') throw new Error('doSomething unavailable in this runtime build');\n  fn();\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function hasOnRuntimeReady(m: any): m is { onRuntimeReady: (api: any) => void | Promise<void> } {\n  return typeof m?.onRuntimeReady === 'function';\n}","tryCatchPattern":"try {\n  await callLibraryInitializerOnRuntimeReady([asset, modPromise]);\n} catch (err) {\n  console.error('onRuntimeReady failed for', asset.name, err.cause ?? err);\n  // optionally mark the feature as unavailable and continue\n}","preventionTips":["Type-check api method existence before calling in onRuntimeReady.","Keep initializers version-aligned with the runtime package.","Test initializers in isolation with a mock api before integration."],"tags":["library-initializer","plugin","runtime","startup"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}