{"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":"validation","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/290d5ab72cc1102813fbc0406fb186ceadabc340/src/native/libs/Common/JavaScript/loader/config.ts#L1-L33","documentation":"validateLoaderConfig() in loader/config.ts throws this when loaderConfig.mainAssemblyName is empty/undefined. The main assembly is the entry-point DLL that runMain/runMainAndExit will invoke, so the loader refuses to proceed without it. It is called by HostBuilder.create(), download(), runMain(), runMainAndExit() and once more inside createRuntime().","triggerScenarios":"Invoking dotnet.create()/download()/runMain() on a HostBuilder that never received mainAssemblyName — i.e. neither withMainAssembly(...) was called nor a config object containing mainAssemblyName was merged via withConfig(...).","commonSituations":"Publishing without a boot config (blazor.boot.json / dotnet.js config) that normally supplies mainAssemblyName; programmatically building the host in a custom harness and forgetting the WithMainAssembly step; the merged config object had mainAssemblyName set to an empty string.","solutions":["Call builder.withMainAssembly('YourApp') (without the .dll extension) before create()/runMain().","Alternatively pass it via withConfig({ mainAssemblyName: 'YourApp', resources: {...} }) with the rest of the config.","Ensure the generated boot config JSON is being loaded and merged (mergeLoaderConfig) — if you replace the default config load, re-add mainAssemblyName.","Confirm the value is not an empty string; the check is truthy, so '' fails validation."],"exampleFix":"// before\nconst dotnet = await dotnet.create();\n\n// after\nconst dotnet = await dotnet.withMainAssembly('MyApp').create();","handlingStrategy":"validation","validationCode":"import { getLoaderConfig } from './loader/config';\nconst cfg = getLoaderConfig();\nif (!cfg.mainAssemblyName) {\n  throw new Error('Call builder.withMainAssembly(name) before create().');\n}","typeGuard":"function hasMainAssembly(c: any): c is { mainAssemblyName: string } {\n  return typeof c?.mainAssemblyName === 'string' && c.mainAssemblyName.length > 0;\n}","tryCatchPattern":"try {\n  await builder.create();\n} catch (err) {\n  if (/mainAssemblyName.*required/.test(err.message)) {\n    builder.withMainAssembly('MyApp');\n    await builder.create();\n  } else throw err;\n}","preventionTips":["Always chain .withMainAssembly('App') in your bootstrap helper.","Centralize host construction in one factory and assert mainAssemblyName in tests.","Treat an empty-string mainAssemblyName as invalid in your config loader."],"tags":["config","validation","startup","loader"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}