{"record":{"id":"2036f359067ffb61","repo":"dotnet/aspnetcore","slug":"cannot-set-a-key-on-a-frame-of-type-parentframe-f","errorCode":null,"errorMessage":"Cannot set a key on a frame of type {parentFrame.FrameTypeField}.","messagePattern":"Cannot set a key on a frame of type (.+?)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/Rendering/RenderTreeBuilder.cs","lineNumber":554,"sourceCode":"\n        var parentFrameIndex = GetCurrentParentFrameIndex();\n        if (!parentFrameIndex.HasValue)\n        {\n            throw new InvalidOperationException(\"Cannot set a key outside the scope of a component or element.\");\n        }\n\n        var parentFrameIndexValue = parentFrameIndex.Value;\n        ref var parentFrame = ref _entries.Buffer[parentFrameIndexValue];\n        switch (parentFrame.FrameTypeField)\n        {\n            case RenderTreeFrameType.Element:\n                parentFrame.ElementKeyField = value; // It's a ref var, so this writes to the array\n                break;\n            case RenderTreeFrameType.Component:\n                parentFrame.ComponentKeyField = value; // It's a ref var, so this writes to the array\n                break;\n            default:\n                throw new InvalidOperationException($\"Cannot set a key on a frame of type {parentFrame.FrameTypeField}.\");\n        }\n    }\n\n    private void OpenComponentUnchecked(int sequence, [DynamicallyAccessedMembers(Component)] Type componentType)\n    {\n        // We are entering a new scope, since we track the \"duplicate attributes\" per\n        // element/component we might need to clean them up now.\n        if (_hasSeenAddMultipleAttributes)\n        {\n            var indexOfLastElementOrComponent = _openElementIndices.Peek();\n            ProcessDuplicateAttributes(first: indexOfLastElementOrComponent + 1);\n        }\n\n        _openElementIndices.Push(_entries.Count);\n        _entries.AppendComponent(sequence, componentType);\n        _lastNonAttributeFrameType = RenderTreeFrameType.Component;\n    }\n","sourceCodeStart":536,"sourceCodeEnd":572,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Components/src/Rendering/RenderTreeBuilder.cs#L536-L572","documentation":"After confirming a parent frame exists, RenderTreeBuilder.SetKey checks the parent frame's type. Keys can only be set on Element or Component frames. If the current parent is a different frame type (e.g., Region), it throws InvalidOperationException with the actual frame type in the message. This prevents assigning keys to structural frames that don't support keyed tracking.","triggerScenarios":"Calling builder.SetKey when the current open scope is a Region frame (opened via OpenRegion) or another non-element/non-component frame type. This can occur in manual RenderTreeBuilder code that opens a region and then tries to set a key on it, or in generated code from unusual Razor constructs.","commonSituations":"Custom RenderTreeBuilder code using OpenRegion followed by SetKey; source generators emitting key directives inside region scopes; misuse of the builder API where a region is the current scope.","solutions":["Only call SetKey when the current open frame is an Element (OpenElement) or Component (OpenComponent).","Move the SetKey call inside the correct element or component scope, not a region scope.","Close the region and open an element/component before calling SetKey.","Review the frame stack to ensure the innermost open frame is Element or Component."],"exampleFix":"// before\nbuilder.OpenRegion(0);\nbuilder.SetKey(\"myKey\"); // parent is Region -> throws\nbuilder.CloseRegion();\n\n// after\nbuilder.OpenElement(0, \"div\");\nbuilder.SetKey(\"myKey\");\nbuilder.CloseElement();","handlingStrategy":"validation","validationCode":"// Ensure the current open scope is Element or Component before SetKey\n// No public API to check current frame type; ensure correct call ordering\nbuilder.OpenElement(0, \"div\");\nbuilder.SetKey(\"myKey\"); // valid: parent is Element\nbuilder.CloseElement();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only call SetKey when the innermost open frame is Element or Component.","Never call SetKey inside a Region scope (after OpenRegion).","Maintain a mental model of the frame stack when writing manual render code.","Add unit tests that exercise SetKey within different frame scopes."],"tags":["blazor","rendertreebuilder","key","region","frame-type","manual-render"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}