dotnet/aspnetcore · error · InvalidOperationException
Cannot set a key on a frame of type {parentFrame.FrameTypeFi
Error message
Cannot set a key on a frame of type {parentFrame.FrameTypeField}. What it means
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.
Source
Thrown at src/Components/Components/src/Rendering/RenderTreeBuilder.cs:554
var parentFrameIndex = GetCurrentParentFrameIndex();
if (!parentFrameIndex.HasValue)
{
throw new InvalidOperationException("Cannot set a key outside the scope of a component or element.");
}
var parentFrameIndexValue = parentFrameIndex.Value;
ref var parentFrame = ref _entries.Buffer[parentFrameIndexValue];
switch (parentFrame.FrameTypeField)
{
case RenderTreeFrameType.Element:
parentFrame.ElementKeyField = value; // It's a ref var, so this writes to the array
break;
case RenderTreeFrameType.Component:
parentFrame.ComponentKeyField = value; // It's a ref var, so this writes to the array
break;
default:
throw new InvalidOperationException($"Cannot set a key on a frame of type {parentFrame.FrameTypeField}.");
}
}
private void OpenComponentUnchecked(int sequence, [DynamicallyAccessedMembers(Component)] Type componentType)
{
// We are entering a new scope, since we track the "duplicate attributes" per
// element/component we might need to clean them up now.
if (_hasSeenAddMultipleAttributes)
{
var indexOfLastElementOrComponent = _openElementIndices.Peek();
ProcessDuplicateAttributes(first: indexOfLastElementOrComponent + 1);
}
_openElementIndices.Push(_entries.Count);
_entries.AppendComponent(sequence, componentType);
_lastNonAttributeFrameType = RenderTreeFrameType.Component;
}
View on GitHub (pinned to 294cab2f9b)
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.
Example fix
// before
builder.OpenRegion(0);
builder.SetKey("myKey"); // parent is Region -> throws
builder.CloseRegion();
// after
builder.OpenElement(0, "div");
builder.SetKey("myKey");
builder.CloseElement(); Defensive patterns
Strategy: validation
Validate before calling
// Ensure the current open scope is Element or Component before SetKey
// No public API to check current frame type; ensure correct call ordering
builder.OpenElement(0, "div");
builder.SetKey("myKey"); // valid: parent is Element
builder.CloseElement(); Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Cannot set a key outside the scope of a component or element
- More than one sibling has the same key value, '{key}'. Key v
- Valueless attributes may only be added immediately after fra
- No preceding attribute frame exists.
- Incorrect frame type: '{prevFrame.FrameTypeField}'
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/2036f359067ffb61.
Report an issue: GitHub.