{"record":{"id":"8d1dfba46d7e6876","repo":"dotnet/aspnetcore","slug":"cannot-set-a-key-outside-the-scope-of-a-component","errorCode":null,"errorMessage":"Cannot set a key outside the scope of a component or element.","messagePattern":"Cannot set a key outside the scope of a component or element\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/Rendering/RenderTreeBuilder.cs","lineNumber":540,"sourceCode":"    }\n\n    /// <summary>\n    /// Assigns the specified key value to the current element or component.\n    /// </summary>\n    /// <param name=\"value\">The value for the key.</param>\n    public void SetKey(object? value)\n    {\n        if (value == null)\n        {\n            // Null is equivalent to not having set a key, which is valuable because Razor syntax doesn't have an\n            // easy way to have conditional directive attributes\n            return;\n        }\n\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)","sourceCodeStart":522,"sourceCodeEnd":558,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Components/src/Rendering/RenderTreeBuilder.cs#L522-L558","documentation":"RenderTreeBuilder.SetKey assigns a @key to the current open element or component. It locates the current parent frame index via GetCurrentParentFrameIndex(); if there is no open element or component (the frame stack is empty or the current scope is not an element/component), it throws InvalidOperationException. Keys can only be set within the scope of an element or component frame.","triggerScenarios":"Calling builder.SetKey(myKey) when no element or component is currently open (i.e., at the top level of the builder, or after CloseElement/CloseComponent without a new Open). This corresponds to placing @key outside of any element or component in Razor markup.","commonSituations":"Placing @key before an element/component tag in Razor; calling SetKey at the top level of a render fragment; calling SetKey after closing the last frame; generated code that emits SetKey in the wrong position.","solutions":["Ensure SetKey is called after OpenElement/OpenComponent and before CloseElement/CloseComponent.","In Razor, place @key as an attribute on an element or component, not as a standalone directive.","Check the call ordering: OpenElement -> ... -> SetKey -> CloseElement.","Remove the @key directive if it's not attached to a specific element or component."],"exampleFix":"<!-- before (Razor) -->\n@key(\"myKey\")\n<div>Hello</div>\n\n<!-- after -->\n<div @key=\"myKey\">Hello</div>","handlingStrategy":"validation","validationCode":"// In Razor, ensure @key is on an element or component\n// In manual code, ensure OpenElement/OpenComponent precedes SetKey\nbuilder.OpenElement(0, \"div\");\nbuilder.SetKey(\"myKey\");\nbuilder.CloseElement();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Place @key as an attribute on an element or component tag, never standalone.","In manual RenderTreeBuilder code, call SetKey only between Open* and Close* calls.","Review Razor markup for @key placement during code reviews.","Test render fragments that use @key to catch ordering errors early."],"tags":["blazor","rendertreebuilder","key","element","scope","manual-render"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}