dotnet/aspnetcore · error · InvalidOperationException

Do not specify both 'Authorized' and 'ChildContent'.

Error message

Do not specify both 'Authorized' and 'ChildContent'.

What it means

Thrown by AuthorizeViewCore.OnParametersSetAsync when a developer supplies both the ChildContent render fragment (the default unnamed child) and the explicit Authorized render fragment. They are functionally equivalent for the authorized case, so supplying both is ambiguous and rejected to prevent confusion.

Solutions

  1. Remove one of the two: either delete the inline body and keep <Authorized>...</Authorized>, or delete the <Authorized> template and rely on the inline content.
  2. Use <Authorized>/<Authorizing>/<NotAuthorized> as a set for full control, and leave the inline content empty.
  3. Validate the .razor markup renders in the designer / dotnet build before running.

Example fix

<!-- before: both inline and Authorized -->
<AuthorizeView>
    <p>Welcome back!</p>
    <Authorized><p>Welcome back!</p></Authorized>
</AuthorizeView>

<!-- after: keep only Authorized -->
<AuthorizeView>
    <Authorized><p>Welcome back!</p></Authorized>
</AuthorizeView>
Defensive patterns

Strategy: validation

Validate before calling

<!-- In the .razor file, ensure only one of inline body or <Authorized> is present. -->
@if (authorizeViewChildContent != null && authorizeViewAuthorized != null) { throw new InvalidOperationException("Pick one"); }

Prevention

When it happens

Trigger: Authoring a <AuthorizeView> (or derived AuthorizeViewRole/Policy) that has both inline body content (ChildContent) and an <Authorized> child template inside the same component.

Common situations: Copy-pasting examples that combine the convenience inline form with the <Authorized> template; migrating from inline-only to template-based and forgetting to remove the inline content; tooling that auto-generates a default fragment.

Related errors


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

Appendix: source

Thrown at src/Components/Authorization/src/AuthorizeViewCore.cs:80

        {
            var authorized = Authorized ?? ChildContent;
            builder.AddContent(0, authorized?.Invoke(currentAuthenticationState!));
        }
        else
        {
            builder.AddContent(0, NotAuthorized?.Invoke(currentAuthenticationState!));
        }
    }

    /// <inheritdoc />
    protected override async Task OnParametersSetAsync()
    {
        // We allow 'ChildContent' for convenience in basic cases, and 'Authorized' for symmetry
        // with 'NotAuthorized' in other cases. Besides naming, they are equivalent. To avoid
        // confusion, explicitly prevent the case where both are supplied.
        if (ChildContent != null && Authorized != null)
        {
            throw new InvalidOperationException($"Do not specify both '{nameof(Authorized)}' and '{nameof(ChildContent)}'.");
        }

        if (AuthenticationState == null)
        {
            throw new InvalidOperationException($"Authorization requires a cascading parameter of type Task<{nameof(AuthenticationState)}>. Consider using {typeof(CascadingAuthenticationState).Name} to supply this.");
        }

        // Clear the previous result of authorization
        // This will cause the Authorizing state to be displayed until the authorization has been completed
        isAuthorized = null;

        currentAuthenticationState = await AuthenticationState;
        isAuthorized = await IsAuthorizedAsync(currentAuthenticationState.User);
    }

    /// <summary>
    /// Gets the data required to apply authorization rules.
    /// </summary>

View on GitHub (pinned to 3600ca084e)