dotnet/aspnetcore · error · ArgumentException

Invalid layout type: does not implement .

Error message

Invalid layout type: {layoutType.FullName} does not implement {typeof(IComponent).FullName}.

What it means

The type passed to LayoutAttribute must implement IComponent, because a layout is itself a Blazor component that renders a Body fragment. Passing a plain class, interface, or record is rejected with ArgumentException.

Solutions

  1. Make the layout a Razor component (it inherits ComponentBase, which implements IComponent).
  2. Verify the type reference resolves to the intended layout component.
  3. Use @layout directive or [Layout(typeof(MyLayout))] with a real component type.

Example fix

// before
[Layout(typeof(SomePlainClass))]
// after
[Layout(typeof(MyLayout))]  // MyLayout.razor : ComponentBase
Defensive patterns

Strategy: type-guard

Validate before calling

if (!typeof(IComponent).IsAssignableFrom(layoutType))
    throw new ArgumentException($"{layoutType} must implement IComponent.");

Type guard

static bool IsValidLayout(Type t) => typeof(IComponent).IsAssignableFrom(t);

Prevention

When it happens

Trigger: [Layout(typeof(NonComponentClass))] where NonComponentClass does not implement IComponent.

Common situations: Pointing LayoutAttribute at a plain C# class, a stale type reference after renaming, or a type that is data-only rather than a Razor component.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/8bf7b2395098dbe6. Report an issue: GitHub.

Appendix: source

Thrown at src/Components/Components/src/LayoutAttribute.cs:25

namespace Microsoft.AspNetCore.Components;

/// <summary>
/// Indicates that the associated component type uses a specified layout.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public sealed class LayoutAttribute : Attribute
{
    /// <summary>
    /// Constructs an instance of <see cref="LayoutAttribute"/>.
    /// </summary>
    /// <param name="layoutType">The type of the layout.</param>
    public LayoutAttribute([DynamicallyAccessedMembers(Component)] Type layoutType)
    {
        LayoutType = layoutType ?? throw new ArgumentNullException(nameof(layoutType));

        if (!typeof(IComponent).IsAssignableFrom(layoutType))
        {
            throw new ArgumentException($"Invalid layout type: {layoutType.FullName} " +
                $"does not implement {typeof(IComponent).FullName}.");
        }

        // Note that we can't validate its acceptance of a 'Body' parameter at this stage,
        // because the contract doesn't force them to be known statically. However it will
        // be a runtime error if the referenced component type rejects the 'Body' parameter
        // when it gets used.
    }

    /// <summary>
    /// The type of the layout. The type must implement <see cref="IComponent"/>
    /// and must accept a parameter with the name 'Body'.
    /// </summary>
    [DynamicallyAccessedMembers(Component)]
    public Type LayoutType { get; private set; }
}

View on GitHub (pinned to 3600ca084e)