{"record":{"id":"74ddbcd7c22face8","repo":"dotnet/runtime","slug":"failed-to-invoke-onruntimeconfigloaded-on-librar","errorCode":null,"errorMessage":"Failed to invoke 'onRuntimeConfigLoaded' on library initializer '${name}': ${message}","messagePattern":"Failed to invoke 'onRuntimeConfigLoaded' on library initializer '(.+?)': (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/native/libs/Common/JavaScript/loader/assets.ts","lineNumber":82,"sourceCode":"        if (!asset.resolvedUrl) throw new Error(\"Invalid config, resources is not set\");\n        mod = await import(/* webpackIgnore: true */ asset.resolvedUrl);\n        asset.moduleExports = mod;\n    }\n    onDownloadedAsset(assetInternal);\n    return mod;\n}\n\nexport async function callLibraryInitializerOnRuntimeConfigLoaded(asset: JsAsset): Promise<any> {\n    const module = await loadJSModule(asset);\n    const name = asset.name || asset.resolvedUrl || \"unknown\";\n    try {\n        if (typeof module.onRuntimeConfigLoaded === \"function\") {\n            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++;","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/native/libs/Common/JavaScript/loader/assets.ts#L64-L100","documentation":"callLibraryInitializerOnRuntimeConfigLoaded loads a JS library-initializer module and awaits its optional onRuntimeConfigLoaded(loaderConfig) hook inside try/catch. If that user-defined hook throws, the error is re-thrown with the module name and the original as cause. This fires for modules listed under resources.modulesAfterConfigLoaded.","triggerScenarios":"A library initializer module (registered via modulesAfterConfigLoaded in the boot config) exports an onRuntimeConfigLoaded function that throws synchronously or rejects asynchronously. The hook receives the mutable loaderConfig object.","commonSituations":"A Blazor/.NET library initializer that reads a config field that is missing; an initializer expecting a specific runtime version; a bug in the initializer's config validation; an initializer that calls a DOM API unavailable in the current host (e.g. Node).","solutions":["Read the '${name}' and '${message}' in the error to identify which initializer module and which line/logic failed.","Open that module's onRuntimeConfigLoaded implementation and fix the throw (guard the missing field, or fix the bug).","If the initializer is from a NuGet package, upgrade or downgrade the package to match the runtime version.","Temporarily remove the initializer entry from modulesAfterConfigLoaded to isolate whether the runtime starts without it."],"exampleFix":"// before — initializer throws on missing config\nexport function onRuntimeConfigLoaded(cfg) {\n  doSetup(cfg.extensions.myFeature.key); // throws if undefined\n}\n\n// after — guard the field\nexport function onRuntimeConfigLoaded(cfg) {\n  const key = cfg.extensions?.myFeature?.key;\n  if (!key) { console.warn('myFeature not configured'); return; }\n  doSetup(key);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"// Narrow a module that exports the hook safely\nfunction hasOnConfigLoaded(m: any): m is { onRuntimeConfigLoaded: (cfg: any) => void | Promise<void> } {\n  return typeof m?.onRuntimeConfigLoaded === 'function';\n}","tryCatchPattern":"try {\n  await callLibraryInitializerOnRuntimeConfigLoaded(asset);\n} catch (err) {\n  // err.cause is the original initializer error\n  console.error('Initializer failed:', asset.name, err.cause ?? err);\n  // decide: skip this initializer or fail startup\n}","preventionTips":["Wrap your onRuntimeConfigLoaded body in its own try/catch and degrade gracefully.","Validate cfg fields you read with optional chaining before use.","Pin the package version of any library that ships an initializer."],"tags":["library-initializer","plugin","runtime","config","startup"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}