{"record":{"id":"3485eeff002affdb","repo":"dotnet/aspnetcore","slug":"there-is-already-a-subscriber-to-the-content-with","errorCode":null,"errorMessage":"There is already a subscriber to the content with the given section ID '{identifier}'.","messagePattern":"There is already a subscriber to the content with the given section ID '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/Sections/SectionRegistry.cs","lineNumber":69,"sourceCode":"        if (index == providers.Count)\n        {\n            // We just removed the most recently added provider, meaning we need to change\n            // the current content to that of second most recently added provider.\n            var contentProvider = GetCurrentProviderContentOrDefault(providers);\n            NotifyContentChangedForSubscriber(identifier, contentProvider);\n\n            if (_subscribersByIdentifier.TryGetValue(identifier, out var subscriber))\n            {\n                DetectRenderModeMismatch(identifier, subscriber, contentProvider);\n            }\n        }\n    }\n\n    public void Subscribe(object identifier, SectionOutlet subscriber)\n    {\n        if (_subscribersByIdentifier.ContainsKey(identifier))\n        {\n            throw new InvalidOperationException($\"There is already a subscriber to the content with the given section ID '{identifier}'.\");\n        }\n\n        // Notify the new subscriber with any existing content.\n        var provider = GetCurrentProviderContentOrDefault(identifier);\n        subscriber.ContentUpdated(provider);\n\n        _subscribersByIdentifier.Add(identifier, subscriber);\n\n        DetectRenderModeMismatch(identifier, subscriber, provider);\n    }\n\n    public void Unsubscribe(object identifier)\n    {\n        if (!_subscribersByIdentifier.Remove(identifier))\n        {\n            throw new InvalidOperationException($\"The subscriber with the given section ID '{identifier}' is already unsubscribed.\");\n        }\n","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Components/src/Sections/SectionRegistry.cs#L51-L87","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"<!-- before: two outlets, one name -->\n<SectionOutlet SectionName=\"main\" />\n<SectionOutlet SectionName=\"main\" /> <!-- throws [342] -->\n\n<!-- after: unique identifiers -->\n<SectionOutlet SectionName=\"main\" />\n<SectionOutlet SectionName=\"secondary\" />","handlingStrategy":"validation","validationCode":"<!-- Scan the component tree at design time for duplicate SectionName/SectionId on SectionOutlet -->\n@* In a test or static check, collect all SectionOutlet SectionName literals and assert uniqueness. *@\n@* Razor: ensure each outlet uses a distinct identifier: *@\n<SectionOutlet SectionName=\"@($\"region-{RegionId}\")\" />","typeGuard":"// C#: validate uniqueness before render in your own component\nstatic bool HasUniqueOutletIdentifiers(IEnumerable<object> ids) => ids.Distinct().Count() == ids.Count();","tryCatchPattern":null,"preventionTips":["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."],"tags":["blazor","components","sections","duplicate","invalidoperation"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}