{"record":{"id":"b6b5b6240743f12b","repo":"dotnet/runtime","slug":"loader-configuration-error-mainassemblyname-is","errorCode":null,"errorMessage":"Loader configuration error: 'mainAssemblyName' is required.","messagePattern":"Loader configuration error: 'mainAssemblyName' is required\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/native/libs/Common/JavaScript/loader/config.ts","lineNumber":15,"sourceCode":"// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nimport type { Assets, LoaderConfig, LoaderConfigInternal } from \"./types\";\nimport { browserVirtualAppBase } from \"./per-module\";\n\nexport const loaderConfig: LoaderConfigInternal = {};\n\nexport function getLoaderConfig(): LoaderConfig {\n    return loaderConfig;\n}\n\nexport function validateLoaderConfig(): void {\n    if (!loaderConfig.mainAssemblyName) {\n        throw new Error(\"Loader configuration error: 'mainAssemblyName' is required.\");\n    }\n    if (!loaderConfig.resources || !loaderConfig.resources.coreAssembly || loaderConfig.resources.coreAssembly.length === 0) {\n        throw new Error(\"Loader configuration error: 'resources.coreAssembly' is required and must contain at least one assembly.\");\n    }\n}\n\nexport function mergeLoaderConfig(source: Partial<LoaderConfigInternal>): void {\n    defaultConfig(loaderConfig);\n    normalizeConfig(source);\n    mergeConfigs(loaderConfig, source);\n}\n\nfunction mergeConfigs(target: LoaderConfigInternal, source: Partial<LoaderConfigInternal>): LoaderConfigInternal {\n    // no need to merge the same object\n    if (target === source || source === undefined || source === null) return target;\n\n    // Merge collections: target values first, then source values appended/spread on top.\n    mergeResources(target.resources!, source.resources!);","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/native/libs/Common/JavaScript/loader/config.ts#L1-L33","documentation":"validateLoaderConfig() throws when loaderConfig.mainAssemblyName is falsy. The main assembly is the entry point the runtime executes via runMain(name, args); without it the loader cannot boot the CLR application. This is a hard precondition — every runtime startup path (create, runMain, runMainAndExit, download) calls validateLoaderConfig first.","triggerScenarios":"Constructing dotnet.withConfig({}) without mainAssemblyName. Calling create()/runMain() before withMainAssembly(). Bootstrapping from a malformed dotnet.*.js script tag where the data-main attribute was removed. Custom bootstrap that skips the withMainAssembly step.","commonSituations":"Copied a sample config and forgot the mainAssemblyName line. Renamed the entry assembly (e.g. from App.dll to MyApp.dll) without updating the bootstrap. Used createDotnetRuntime with a partial config object. The MSBuild <WasmMainAssemblyPath> was unset so the generated config omits the name.","solutions":["Call builder.withMainAssembly('MyApp.dll') before create()/runMain().","Or pass mainAssemblyName inside withConfig({ mainAssemblyName: 'MyApp.dll', resources: {...} }).","If using the generated dotnet.boot.config.json, ensure the build produced it; check the <WasmMainAssemblyPath> MSBuild property.","Confirm the assembly exists in resources.assembly or resources.coreAssembly too (else error 107 follows)."],"exampleFix":"// before\nconst runtime = await dotnet.create();\n\n// after\nconst runtime = await dotnet\n  .withMainAssembly('MyApp.dll')\n  .create();","handlingStrategy":"validation","validationCode":"function hasMainAssembly(cfg: any): cfg is { mainAssemblyName: string } {\n  return typeof cfg?.mainAssemblyName === 'string' && cfg.mainAssemblyName.length > 0;\n}\nif (!hasMainAssembly(myConfig)) throw new Error('mainAssemblyName missing');","typeGuard":"function isLoaderConfigWithMain(c: unknown): c is { mainAssemblyName: string } {\n  return !!c && typeof c === 'object' && typeof (c as any).mainAssemblyName === 'string';\n}","tryCatchPattern":"try { await dotnet.create(); } catch (e) {\n  if (/mainAssemblyName.*required/.test((e as Error).message)) {\n    dotnet.withMainAssembly('MyApp.dll');\n    // retry\n  } else throw e;\n}","preventionTips":["Always load the MSBuild-generated dotnet.boot.config.json rather than hand-crafting config.","Add a startup assertion in tests that calls validateLoaderConfig() before create().","When renaming the entry assembly, update every bootstrap that references its name.","Keep the entry assembly name in a single constant shared between .csproj and bootstrap."],"tags":["configuration","loader","startup"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}