dotnet/aspnetcore · error · InvalidOperationException
{nameof(SectionContent)} requires that '{nameof(SectionName)
Error message
{nameof(SectionContent)} requires that '{nameof(SectionName)}' and '{nameof(SectionId)}' cannot both have non-null values. What it means
SectionContent identifies the section it supplies content for by either a string name (SectionName) or an object identifier (SectionId), but not both. The two are mutually exclusive identification modes; if both are non-null the component cannot decide which to register under, so SetParametersAsync throws InvalidOperationException. The check runs before the registry is touched, so no partial state is committed.
Source
Thrown at src/Components/Components/src/Sections/SectionContent.cs:56
[Parameter] public RenderFragment? ChildContent { get; set; }
void IComponent.Attach(RenderHandle renderHandle)
{
SectionRenderMode = renderHandle.RenderMode;
_registry = renderHandle.SectionRegistry;
}
Task IComponent.SetParametersAsync(ParameterView parameters)
{
// We are not using parameters.SetParameterProperties(this)
// because IsDefaultContent is internal property and not a parameter
SetParameterValues(parameters);
object? identifier;
if (SectionName is not null && SectionId is not null)
{
throw new InvalidOperationException($"{nameof(SectionContent)} requires that '{nameof(SectionName)}' and '{nameof(SectionId)}' cannot both have non-null values.");
}
else if (SectionName is not null)
{
identifier = SectionName;
}
else if (SectionId is not null)
{
identifier = SectionId;
}
else
{
throw new InvalidOperationException($"{nameof(SectionContent)} requires a non-null value either for '{nameof(SectionName)}' or '{nameof(SectionId)}'.");
}
if (!object.Equals(identifier, _registeredIdentifier) || IsDefaultContent != _registeredIsDefaultContent)
{
if (_registeredIdentifier is not null)
{View on GitHub (pinned to 3600ca084e)
Solutions
- Pick one identifier style and remove the other attribute from <SectionContent>.
- Use SectionName for static, declarative sections; use SectionId (a shared object instance) for sections resolved across components without magic strings.
- If the design needs both, split into two SectionContent elements targeted at different outlets.
Example fix
// before <SectionContent SectionName="banner" SectionId="@myId">...</SectionContent> // after — name only <SectionContent SectionName="banner">...</SectionContent>
Defensive patterns
Strategy: validation
Validate before calling
// In markup, set exactly one identifier. Programmatic check:
if (sectionName is not null && sectionId is not null)
throw new InvalidOperationException("Set SectionName XOR SectionId, not both."); Type guard
static bool IsExclusiveSectionIdentifier(string? name, object? id)
=> (name is not null) ^ (id is not null); Prevention
- Standardize on one identification style per project (name vs object id).
- Use shared constants or a single shared object instance so the SectionContent and SectionOutlet pair is unambiguous.
- Code-review SectionContent usages when migrating between identifier styles.
When it happens
Trigger: Setting both SectionName="foo" and SectionId="@someObject" on the same <SectionContent> element. The properties are distinct [Parameter]s that are both populated from markup.
Common situations: Switching from name-based to id-based sections and leaving the old attribute in markup; copy-pasting from samples that use different identification styles; auto-completion adding both attributes.
Related errors
- {nameof(SectionContent)} requires a non-null value either fo
- {nameof(SectionOutlet)} requires that '{nameof(SectionName)}
- {nameof(SectionOutlet)} requires a non-null value either for
- The {nameof(Router)} component requires a value for the para
- The {nameof(Router)} component requires a value for the para
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/79ee9f3e3c510493.
Report an issue: GitHub.