{"record":{"id":"e35e753b6f950120","repo":"dotnet/aspnetcore","slug":"component-reference-captures-may-only-be-added-as","errorCode":null,"errorMessage":"Component reference captures may only be added as children of frames of type Component","messagePattern":"Component reference captures may only be added as children of frames of type Component","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/Rendering/RenderTreeBuilder.cs","lineNumber":617,"sourceCode":"        {\n            throw new InvalidOperationException($\"Element reference captures may only be added as children of frames of type {RenderTreeFrameType.Element}\");\n        }\n\n        _entries.AppendElementReferenceCapture(sequence, elementReferenceCaptureAction);\n        _lastNonAttributeFrameType = RenderTreeFrameType.ElementReferenceCapture;\n    }\n\n    /// <summary>\n    /// Appends a frame representing an instruction to capture a reference to the parent component.\n    /// </summary>\n    /// <param name=\"sequence\">An integer that represents the position of the instruction in the source code.</param>\n    /// <param name=\"componentReferenceCaptureAction\">An action to be invoked whenever the reference value changes.</param>\n    public void AddComponentReferenceCapture(int sequence, Action<object> componentReferenceCaptureAction)\n    {\n        var parentFrameIndex = GetCurrentParentFrameIndex();\n        if (!parentFrameIndex.HasValue)\n        {\n            throw new InvalidOperationException(ComponentReferenceCaptureInvalidParentMessage);\n        }\n\n        var parentFrameIndexValue = parentFrameIndex.Value;\n        if (_entries.Buffer[parentFrameIndexValue].FrameTypeField != RenderTreeFrameType.Component)\n        {\n            throw new InvalidOperationException(ComponentReferenceCaptureInvalidParentMessage);\n        }\n\n        _entries.AppendComponentReferenceCapture(sequence, componentReferenceCaptureAction, parentFrameIndexValue);\n        _lastNonAttributeFrameType = RenderTreeFrameType.ComponentReferenceCapture;\n    }\n\n    /// <summary>\n    /// Adds a frame indicating the render mode on the enclosing component frame.\n    /// </summary>\n    /// <param name=\"renderMode\">The <see cref=\"IComponentRenderMode\"/>.</param>\n    public void AddComponentRenderMode(IComponentRenderMode? renderMode)\n    {","sourceCodeStart":599,"sourceCodeEnd":635,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Components/src/Rendering/RenderTreeBuilder.cs#L599-L635","documentation":"Thrown by RenderTreeBuilder.AddComponentReferenceCapture (the frame emitted for a child-component @ref capture) when GetCurrentParentFrameIndex() returns null — the _openElementIndices stack is empty, so there is no enclosing frame of any kind. A component-reference capture must be a child of the component it references.","triggerScenarios":"Calling builder.AddComponentReferenceCapture(seq, action) at the top level of a RenderFragment with no preceding Open*/OpenComponent. Equivalent to a @ref on a component placed outside any parent scope in hand-built tree code.","commonSituations":"Hand-written RenderFragment that appends the capture before OpenComponent; logic that conditionally opens a component but unconditionally runs the capture; a stray capture left after deleting an OpenComponent call.","solutions":["Wrap the AddComponentReferenceCapture call inside OpenComponent(...)/CloseComponent() for the component it captures.","If the component open is conditional, make the capture conditional too (guard both with the same if).","Remove capture calls that no longer correspond to any OpenComponent."],"exampleFix":"// before\nbuilder.AddComponentReferenceCapture(1, r => _comp = r);\nbuilder.OpenComponent<MyComp>(0);\nbuilder.CloseComponent();\n\n// after\nbuilder.OpenComponent<MyComp>(0);\nbuilder.AddComponentParameter(1, ...);\nbuilder.AddComponentReferenceCapture(2, r => _comp = r);\nbuilder.CloseComponent();","handlingStrategy":"validation","validationCode":"// No public accessor for parent existence. Guarantee the capture is inside OpenComponent by structure.\nbool _componentOpen = false;\nvoid Render(RenderTreeBuilder b) {\n    b.OpenComponent<MyComp>(0); _componentOpen = true;\n    if (_componentOpen) b.AddComponentReferenceCapture(1, r => _comp = r);\n    _componentOpen = false; b.CloseComponent();\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair AddComponentReferenceCapture with a preceding OpenComponent in the same scope.","Make component open and capture both conditional on the same flag so neither runs alone.","Prefer .razor @ref on components over hand-written capture frames."],"tags":["blazor","rendering","rendertree","component-reference","manual-renderfragment"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}