dotnet/runtime · error · Error
Loader configuration error: 'resources.coreAssembly' is…
Error message
Loader configuration error: 'resources.coreAssembly' is required and must contain at least one assembly.
What it means
validateLoaderConfig() throws when resources is missing, resources.coreAssembly is missing, or coreAssembly array is empty. coreAssembly holds the framework assemblies (System.Private.CoreLib etc.) that must be present before any user code runs. The boot manifest produced by MSBuild populates this; an empty array means the publish output is incomplete.
Solutions
- Use the dotnet.runtimeconfig.json / dotnet.boot.config.json produced by dotnet publish — do not handcraft resources.
- If merging configs, ensure the source contains coreAssembly before mergeLoaderConfig runs.
- Re-run dotnet publish to regenerate the manifest.
- Verify the SDK version is consistent (coreAssembly was introduced for partitioned framework downloads).
Example fix
// before
builder.withConfig({ mainAssemblyName: 'App.dll', resources: {} });
// after: load the generated manifest
const config = await fetch('./_framework/dotnet.boot.config.json').then(r => r.json());
builder.withConfig(config); Defensive patterns
Strategy: validation
Validate before calling
function hasCoreAssemblies(cfg: any): boolean {
return Array.isArray(cfg?.resources?.coreAssembly) && cfg.resources.coreAssembly.length > 0;
} Type guard
function isValidResources(r: unknown): r is { coreAssembly: unknown[] } {
return !!r && typeof r === 'object' && Array.isArray((r as any).coreAssembly) && (r as any).coreAssembly.length > 0;
} Try / catch
try { await dotnet.create(); } catch (e) {
if (/resources\.coreAssembly.*required/.test((e as Error).message)) {
// reload the boot manifest and retry
} else throw e;
} Prevention
- Never construct LoaderConfig by hand — always use the published boot config.
- Validate resources.coreAssembly.length > 0 in a smoke test after publish.
- Keep SDK versions consistent across build and runtime so the manifest schema matches.
- If merging configs, verify the source has coreAssembly before calling mergeLoaderConfig.
When it happens
Trigger: withConfig called with resources: {} or resources.coreAssembly: []. Manually constructing a LoaderConfig without copying the framework assembly list. A custom boot config that omitted coreAssembly. Build publish output truncated.
Common situations: Hand-editing the generated boot JSON. Migrating from older SDK where coreAssembly was not a separate field. Publishing with a trimmed/incomplete _framework directory. Using a config from a different app.
Related errors
- must be marked with 'BlazorWebAssemblyLazyLoad' item group…
- must be marked with 'BlazorWebAssemblyLazyLoad' item group…
- Invalid config, resources is not set
- Loader configuration error: 'mainAssemblyName' is required.
- method instrumentation is not enabled, please enable it…
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/c10dc4845bebb10f.
Report an issue: GitHub.
Appendix: source
Thrown at src/native/libs/Common/JavaScript/loader/config.ts:18
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
import type { Assets, LoaderConfig, LoaderConfigInternal } from "./types";
import { browserVirtualAppBase } from "./per-module";
export const loaderConfig: LoaderConfigInternal = {};
export function getLoaderConfig(): LoaderConfig {
return loaderConfig;
}
export function validateLoaderConfig(): void {
if (!loaderConfig.mainAssemblyName) {
throw new Error("Loader configuration error: 'mainAssemblyName' is required.");
}
if (!loaderConfig.resources || !loaderConfig.resources.coreAssembly || loaderConfig.resources.coreAssembly.length === 0) {
throw new Error("Loader configuration error: 'resources.coreAssembly' is required and must contain at least one assembly.");
}
}
export function mergeLoaderConfig(source: Partial<LoaderConfigInternal>): void {
defaultConfig(loaderConfig);
normalizeConfig(source);
mergeConfigs(loaderConfig, source);
}
function mergeConfigs(target: LoaderConfigInternal, source: Partial<LoaderConfigInternal>): LoaderConfigInternal {
// no need to merge the same object
if (target === source || source === undefined || source === null) return target;
// Merge collections: target values first, then source values appended/spread on top.
mergeResources(target.resources!, source.resources!);
// For scalar fields with defaults, prefer source when defined, otherwise keep target default.
// We patch source so that Object.assign below copies the correct resolved value.
source.appendElementOnExit = source.appendElementOnExit !== undefined ? source.appendElementOnExit : target.appendElementOnExit;View on GitHub (pinned to 60108ba66e)