{"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/60108ba66eb7d1d12f595480091b4ad80a24b172/src/native/libs/Common/JavaScript/loader/assets.ts#L64-L100","documentation":"Thrown by callLibraryInitializerOnRuntimeConfigLoaded() (src/native/libs/Common/JavaScript/loader/assets.ts:72). It loads a library-initializer JS module and invokes its onRuntimeConfigLoaded(config) hook; if the hook throws (or rejects), the loader wraps the cause and re-throws so the failure is attributable to the offending initializer by name.","triggerScenarios":"A module listed in resources.modulesAfterConfigLoaded exports onRuntimeConfigLoaded; the loader calls it with loaderConfig; if it throws synchronously or returns a rejected promise, the catch at line 80 wraps and rethrows.","commonSituations":"A custom library initializer that reads a missing config field and throws; an initializer written against an older/newer config shape; an initializer that makes a network call which fails; a bug in the initializer's onRuntimeConfigLoaded body.","solutions":["Inspect the wrapped error.cause and the named initializer to find the real exception, then fix the initializer.","Make onRuntimeConfigLoaded defensive about optional config fields (feature-detect before reading).","Ensure the initializer is built/tested against the runtime version whose config shape it expects."],"exampleFix":"// before: initializer throws on missing field\nexport function onRuntimeConfigLoaded(config) {\n  doSetup(config.globalization.icuData); // TypeError if undefined\n}\n\n// after\nexport function onRuntimeConfigLoaded(config) {\n  const icu = config?.globalization?.icuData;\n  if (icu) doSetup(icu);\n}","handlingStrategy":"try-catch","validationCode":"// best-effort: confirm the initializer exports the hook before relying on it\nasync function safeHook(mod: any, cfg: any): Promise<void> {\n  if (typeof mod?.onRuntimeConfigLoaded === 'function') {\n    await mod.onRuntimeConfigLoaded(cfg);\n  }\n}","typeGuard":"function hasOnRuntimeConfigLoaded(m: any): m is { onRuntimeConfigLoaded: (c: 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 initializer's real error; fix that initializer\n  console.error('Initializer failed:', (err as Error).message, (err as any).cause);\n  throw err;\n}","preventionTips":["Make onRuntimeConfigLoaded defensive about optional config fields.","Test initializers against the exact config shape of the deployed runtime.","Never let an initializer swallow exceptions silently; let them propagate with context."],"tags":["library-initializer","configuration","extension-point"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}