dotnet/runtime · error · Error
must be marked with 'BlazorWebAssemblyLazyLoad' item group…
Error message
${assemblyNameToLoad} must be marked with 'BlazorWebAssemblyLazyLoad' item group in your project file to allow lazy-loading. What it means
Thrown by fetchLazyAssembly() when the requested assembly name cannot be matched against any entry in loaderConfig.resources.lazyAssembly. The .NET runtime lazy-load system requires the assembly to be declared at build time so the boot manifest lists it as lazy. Without the manifest entry, the loader has no URL/hash and refuses to load. It is a configuration-vs-request contract violation, not a network problem.
Solutions
- Add <BlazorWebAssemblyLazyLoad Include="AssemblyName.dll" /> to the .csproj that produces the app (not the library).
- Verify the exact name passed to load matches the Include (case-sensitive, with .dll or .wasm extension).
- Rebuild and republish so the boot JSON manifest regenerates with the new lazyAssembly entry.
- If the assembly is loaded eagerly elsewhere, remove the lazy-load request instead, or split the dependency so only lazy parts are lazy.
- For Blazor routing, set Assembly extra in <Router AdditionalAssemblies> AND list it in BlazorWebAssemblyLazyLoad.
Example fix
// before: Router references a lazy page but project lacks the item
// App.razor
<Router AppAssembly="@typeof(Program).Assembly"
AdditionalAssemblies="new[] { typeof(MyPlugin.Pages.Page1).Assembly }" />
// after: add to Server/Client .csproj
<ItemGroup>
<BlazorWebAssemblyLazyLoad Include="MyPlugin.dll" />
</ItemGroup> Defensive patterns
Strategy: validation
Validate before calling
import { loaderConfig } from './config';
function canLazyLoad(assemblyName: string): boolean {
const lazy = loaderConfig.resources?.lazyAssembly ?? [];
const target = assemblyName.replace(/\.(dll|wasm)$/, '');
return lazy.some(a => {
const file = (a as any).virtualPath.split('/').pop() ?? '';
return file.replace(/\.(dll|wasm)$/, '') === target;
});
}
// before calling fetchLazyAssembly:
if (!canLazyLoad('MyPlugin.dll')) {
console.error('Add <BlazorWebAssemblyLazyLoad Include="MyPlugin.dll" /> to .csproj');
} Type guard
function isLazyLoadable(assemblyName: string): assemblyName is string {
const lazy = loaderConfig.resources?.lazyAssembly ?? [];
return lazy.some(a => (a as any).virtualPath?.endsWith(assemblyName));
} Try / catch
try {
await dotnetApi.invokeAssembly('MyPlugin', 'EntryPoint');
} catch (e) {
if (e instanceof Error && e.message.includes('BlazorWebAssemblyLazyLoad')) {
// surface build-config instruction to user
} else throw e;
} Prevention
- Maintain a single source of truth for lazy assemblies (a constants file) and validate the .csproj against it in CI.
- Add a smoke test that attempts to load each declared lazy assembly after publish.
- Wire Router.OnNavigateAsync to pre-touch lazy assemblies so the error surfaces during navigation, not at first component render.
When it happens
Trigger: Calling dotnetApi.invokeAssembly or Platform::LoadAssembly for a name (e.g. 'MyPlugin.dll') that was not declared via <BlazorWebAssemblyLazyLoad Include="MyPlugin.dll" />. Also triggered by Router OnNavigateAsync loading a page whose component sits in an undeclared assembly, or by calling fetchLazyAssembly('Foo') directly when resources.lazyAssembly is empty or omits Foo.
Common situations: Adding a Razor component library referenced only from a lazy route but forgetting the BlazorWebAssemblyLazyLoad item. Renaming an assembly without updating the lazy-load list. Plugin systems that try to load arbitrary DLLs without declaring them at build time. Upgrading .NET version and missing the new requirement to list satellite/dependency assemblies as lazy too.
Related errors
- must be marked with 'BlazorWebAssemblyLazyLoad' item group…
- No assemblies have been marked as lazy-loadable. Use the…
- No assemblies have been marked as lazy-loadable. Use the…
- Loader configuration error: 'resources.coreAssembly' is…
- method instrumentation is not enabled, please enable it…
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/aedbdf4e2f4329b2.
Report an issue: GitHub.
Appendix: source
Thrown at src/native/libs/Common/JavaScript/loader/assets.ts:297
if (loadedLazyAssemblies.has(assemblyNameWithoutExtension)) {
return false;
}
const assemblyNameToLoadDll = assemblyNameWithoutExtension + ".dll";
const assemblyNameToLoadWasm = assemblyNameWithoutExtension + ".wasm";
let dllAsset: AssemblyAsset | null = null;
for (const asset of lazyAssemblies) {
const fileName = lazyAssetFileName(asset.virtualPath);
if (fileName === assemblyNameToLoadDll || fileName === assemblyNameToLoadWasm) {
dllAsset = asset;
break;
}
}
if (!dllAsset) {
throw new Error(`${assemblyNameToLoad} must be marked with 'BlazorWebAssemblyLazyLoad' item group in your project file to allow lazy-loading.`);
}
await fetchAssembly(dllAsset);
loadedLazyAssemblies.add(assemblyNameWithoutExtension);
if (loaderConfig.debugLevel !== 0) {
const pdbNameToLoad = assemblyNameWithoutExtension + ".pdb";
const pdbAssets = loaderConfig.resources?.pdb;
let pdbAssetToLoad: AssemblyAsset | undefined;
if (pdbAssets) {
for (const pdbAsset of pdbAssets) {
if (lazyAssetFileName(pdbAsset.virtualPath) === pdbNameToLoad) {
pdbAssetToLoad = pdbAsset;
break;
}
}
}
if (!pdbAssetToLoad) {View on GitHub (pinned to 60108ba66e)