{"record":{"id":"54cce7d8e3f50b82","repo":"dotnet/aspnetcore","slug":"the-provider-was-not-found-in-the-providers-list-o","errorCode":null,"errorMessage":"The provider was not found in the providers list of the given section ID '{identifier}'.","messagePattern":"The provider was not found in the providers list of the given section ID '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/Sections/SectionRegistry.cs","lineNumber":46,"sourceCode":"        }\n        else\n        {\n            providers.Add(provider);\n        }\n    }\n\n    public void RemoveProvider(object identifier, SectionContent provider)\n    {\n        if (!_providersByIdentifier.TryGetValue(identifier, out var providers))\n        {\n            throw new InvalidOperationException($\"There are no content providers with the given section ID '{identifier}'.\");\n        }\n\n        var index = providers.LastIndexOf(provider);\n\n        if (index < 0)\n        {\n            throw new InvalidOperationException($\"The provider was not found in the providers list of the given section ID '{identifier}'.\");\n        }\n\n        providers.RemoveAt(index);\n\n        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","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Components/src/Sections/SectionRegistry.cs#L28-L64","documentation":"Thrown by SectionRegistry.RemoveProvider when the identifier key exists in _providersByIdentifier but the specific SectionContent instance was not found in its list (List.LastIndexOf returned -1). It indicates a provider that the caller believes is registered was never added to that identifier's list, or was added under a different identifier.","triggerScenarios":"SectionContent.Dispose or SetParametersAsync invokes _registry.RemoveProvider(identifier, this); the identifier is registered but 'this' is not a member of its provider list. Happens when the same SectionContent instance is registered under one identifier and removed under another, when the registry's list was mutated out of band, or when IsDefaultContent flipping caused AddProvider under one path but RemoveProvider under another.","commonSituations":"A SectionContent that swaps SectionId at runtime and the AddProvider/RemoveProvider pair gets out of step because IsDefaultContent also changed (the condition at SectionContent.cs:71 must include IsDefaultContent to re-pair correctly); custom test doubles that drive the registry directly; race during prerendering where the prerendered instance and the interactive instance both attempt removal.","solutions":["When changing both SectionId and IsDefaultContent on the same SectionContent, change them in the same parameter update so SetParametersAsync re-registers atomically (SectionContent.cs:71 already checks both — make sure your usage does too).","Do not share one SectionContent instance across two registries or two identifiers; each instance belongs to exactly one identifier at a time.","Audit any custom code that calls SectionRegistry.RemoveProvider directly to confirm it always passes the identifier the provider was Add'd with.","Reproduce under a debugger with a breakpoint on the throw and inspect _providersByIdentifier[identifier] to see which provider objects are actually listed."],"exampleFix":"// before: identifier swap with mismatched add/remove\n<SectionContent SectionId=\"@oldId\" />\n@* later *@\n<SectionContent SectionId=\"@newId\" /> // if instance identity reused, RemoveProvider may miss\n\n// after: let Blazor recreate the component with a @key so Add/Remove pair cleanly\n<SectionContent SectionId=\"@id\" @key=\"id\" />","handlingStrategy":"validation","validationCode":"// In a unit test exercising a custom host, assert Add/Remove pairing symmetry:\n// var added = new HashSet<SectionContent>();\n// registry.OnAdd = (id, p) => added.Add(p);\n// registry.OnRemove = (id, p) => Assert.Contains(p, added);\n// In app code, simply ensure SectionContent is never reused across identifiers without re-instantiation.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use @key on SectionContent bound to the identifier so a change in identifier recreates the instance instead of repointing it.","Do not mutate IsDefaultContent and SectionId independently across renders; change them together in one SetParametersAsync.","Audit any code that holds a SectionContent reference outside the renderer."],"tags":["blazor","components","sections","lifecycle","invalidoperation"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}