dotnet/aspnetcore · error · InvalidOperationException
There is already a subscriber to the content with the given
Error message
There is already a subscriber to the content with the given section ID '{identifier}'. What it means
Thrown by SectionRegistry.Subscribe when a subscriber (SectionOutlet) is being registered for an identifier that already has a subscriber in the same registry. The SectionRegistry enforces a one-outlet-per-identifier invariant within a single renderer/registry, because the outlet would otherwise have ambiguous content routing.
Source
Thrown at src/Components/Components/src/Sections/SectionRegistry.cs:69
if (index == providers.Count)
{
// We just removed the most recently added provider, meaning we need to change
// the current content to that of second most recently added provider.
var contentProvider = GetCurrentProviderContentOrDefault(providers);
NotifyContentChangedForSubscriber(identifier, contentProvider);
if (_subscribersByIdentifier.TryGetValue(identifier, out var subscriber))
{
DetectRenderModeMismatch(identifier, subscriber, contentProvider);
}
}
}
public void Subscribe(object identifier, SectionOutlet subscriber)
{
if (_subscribersByIdentifier.ContainsKey(identifier))
{
throw new InvalidOperationException($"There is already a subscriber to the content with the given section ID '{identifier}'.");
}
// Notify the new subscriber with any existing content.
var provider = GetCurrentProviderContentOrDefault(identifier);
subscriber.ContentUpdated(provider);
_subscribersByIdentifier.Add(identifier, subscriber);
DetectRenderModeMismatch(identifier, subscriber, provider);
}
public void Unsubscribe(object identifier)
{
if (!_subscribersByIdentifier.Remove(identifier))
{
throw new InvalidOperationException($"The subscriber with the given section ID '{identifier}' is already unsubscribed.");
}
View on GitHub (pinned to 3600ca084e)
Solutions
- Search the component tree for duplicate <SectionOutlet> declarations sharing the same SectionName/SectionId and give each a distinct identifier.
- If you need the same content in multiple places, render the content in one outlet and project it elsewhere via a different mechanism (cascading value, layout reference); do not register two outlets for one identifier.
- For dynamic lists, derive the identifier from the item so each row's outlet is unique (e.g. SectionName=$"row-{item.Id}").
- Ensure that prerendering and interactive rendering are not both creating an outlet for the same identifier in the same registry scope.
Example fix
<!-- before: two outlets, one name --> <SectionOutlet SectionName="main" /> <SectionOutlet SectionName="main" /> <!-- throws [342] --> <!-- after: unique identifiers --> <SectionOutlet SectionName="main" /> <SectionOutlet SectionName="secondary" />
Defensive patterns
Strategy: validation
Validate before calling
<!-- Scan the component tree at design time for duplicate SectionName/SectionId on SectionOutlet -->
@* In a test or static check, collect all SectionOutlet SectionName literals and assert uniqueness. *@
@* Razor: ensure each outlet uses a distinct identifier: *@
<SectionOutlet SectionName="@($"region-{RegionId}")" /> Type guard
// C#: validate uniqueness before render in your own component static bool HasUniqueOutletIdentifiers(IEnumerable<object> ids) => ids.Distinct().Count() == ids.Count();
Prevention
- Give every SectionOutlet a globally-unique SectionName within its renderer scope.
- When rendering outlets from a list, derive the identifier from the item.
- Do not place an outlet in both a prerendered layout and an interactive component for the same identifier.
When it happens
Trigger: Two SectionOutlet components resolve to the same identifier object (same SectionName string or equal SectionId object) and both attach to the same renderer. SectionOutlet.SetParametersAsync (line 72) calls _registry.Subscribe, which throws if _subscribersByIdentifier already contains that key.
Common situations: Placing two <SectionOutlet SectionName="main" /> in the same layout or page; using the same SectionId object instance as a key for two outlets; outlets in a loop or list that share a constant identifier; cross-render-mode confusion where both a prerendered and an interactive outlet mount for the same name.
Related errors
- There are no content providers with the given section ID '{i
- The provider was not found in the providers list of the give
- The subscriber with the given section ID '{identifier}' is a
- The event '${eventName}' is already registered.
- Interop methods are already registered for renderer ${render
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/3485eeff002affdb.
Report an issue: GitHub.