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

  1. Add <BlazorWebAssemblyLazyLoad Include="AssemblyName.dll" /> to the .csproj that produces the app (not the library).
  2. Verify the exact name passed to load matches the Include (case-sensitive, with .dll or .wasm extension).
  3. Rebuild and republish so the boot JSON manifest regenerates with the new lazyAssembly entry.
  4. If the assembly is loaded eagerly elsewhere, remove the lazy-load request instead, or split the dependency so only lazy parts are lazy.
  5. 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

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


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)