dotnet/aspnetcore · error · InvalidOperationException
Setting {nameof(NotFound)} and {nameof(NotFoundPage)} proper
Error message
Setting {nameof(NotFound)} and {nameof(NotFoundPage)} properties simultaneously is not supported. Use either {nameof(NotFound)} or {nameof(NotFoundPage)}. What it means
Router exposes two ways to customize the 404 experience: the legacy NotFound render fragment and the newer NotFoundPage type (a routable component used as the 404 target). They are mutually exclusive because both would attempt to claim the not-found path; setting both at parameter-set time throws InvalidOperationException. The legacy member is decorated [Obsolete] and the warning is suppressed only around the check.
Source
Thrown at src/Components/Components/src/Routing/Router.cs:143
if (AppAssembly == null)
{
throw new InvalidOperationException($"The {nameof(Router)} component requires a value for the parameter {nameof(AppAssembly)}.");
}
// Found content is mandatory, because even though we could use something like <RouteView ...> as a
// reasonable default, if it's not declared explicitly in the template then people will have no way
// to discover how to customize this (e.g., to add authorization).
if (Found == null)
{
throw new InvalidOperationException($"The {nameof(Router)} component requires a value for the parameter {nameof(Found)}.");
}
if (NotFoundPage != null)
{
#pragma warning disable CS0618 // Type or member is obsolete
if (NotFound != null)
{
throw new InvalidOperationException($"Setting {nameof(NotFound)} and {nameof(NotFoundPage)} properties simultaneously is not supported. Use either {nameof(NotFound)} or {nameof(NotFoundPage)}.");
}
#pragma warning restore CS0618 // Type or member is obsolete
if (!typeof(IComponent).IsAssignableFrom(NotFoundPage))
{
throw new InvalidOperationException($"The type {NotFoundPage.FullName} " +
$"does not implement {typeof(IComponent).FullName}.");
}
var routeAttributes = NotFoundPage.GetCustomAttributes(typeof(RouteAttribute), inherit: true);
if (routeAttributes.Length == 0)
{
throw new InvalidOperationException($"The type {NotFoundPage.FullName} " +
$"does not have a {typeof(RouteAttribute).FullName} applied to it.");
}
var routeAttribute = (RouteAttribute)routeAttributes[0];
if (routeAttribute.Template != null)
{View on GitHub (pinned to 3600ca084e)
Solutions
- Choose one mechanism: keep NotFound (render fragment) for inline markup, or NotFoundPage (a routable component) for a full-page 404 — not both.
- Remove whichever attribute you are not using from the Router markup.
- If migrating, delete NotFound from markup at the same commit that introduces NotFoundPage.
Example fix
// before
<Router AppAssembly="@typeof(Program).Assembly"
NotFound="@NotFoundTemplate"
NotFoundPage="@typeof(NotFoundPage)"> <!-- both set -->
// after — pick one
<Router AppAssembly="@typeof(Program).Assembly"
NotFoundPage="@typeof(NotFoundPage)"> Defensive patterns
Strategy: validation
Validate before calling
// Choose one not-found mechanism; this is a markup-level discipline. // <Router ... NotFoundPage="@typeof(NotFound)"> // do NOT also set NotFound
Type guard
static bool IsExclusiveNotFoundSet(RenderFragment? notFound, Type? notFoundPage)
=> !(notFound is not null && notFoundPage is not null); Prevention
- Decide on one 404 strategy for the project (NotFound fragment vs NotFoundPage component) and document it.
- When migrating from NotFound to NotFoundPage, remove the old attribute in the same commit.
- Use code review to catch accidental double-sets.
- Add a startup smoke test rendering App.razor.
When it happens
Trigger: Setting both NotFound="@(...)" and NotFoundPage="typeof(SomeComponent)" on the same <Router> instance. Also by setting them via SetParametersAsync in test code.
Common situations: Migrating from NotFound to NotFoundPage and forgetting to remove the old attribute; copy-pasting across templates that use different approaches; IDE auto-completion adding both attributes.
Related errors
- The {nameof(Router)} component requires a value for the para
- The {nameof(Router)} component requires a value for the para
- The type {NotFoundPage.FullName} does not implement {typeof(
- The type {NotFoundPage.FullName} does not have a {typeof(Rou
- The type {context.Handler.FullName} does not implement {type
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/580dc1b69b31eea0.
Report an issue: GitHub.