dotnet/aspnetcore · error · InvalidOperationException
Incorrect frame type
Error message
Incorrect frame type: '{prevFrame.FrameTypeField}' What it means
SetUpdatesAttributeName was called when the most recent frame is not an Attribute frame. The method must tag a preceding Attribute frame; any other frame type (Element, Component, Region, etc.) is rejected as 'Incorrect frame type'.
Solutions
- Reorder so the immediately preceding frame is the Attribute being tagged.
- Before calling, check _entries last frame type (in custom code: track the last frame type yourself).
- Use the higher-level AddAttribute overloads which preserve correct ordering automatically.
Example fix
// before
builder.AddAttribute(0, "onclick", handler);
builder.AddContent(1, "Click");
builder.SetUpdatesAttributeName("value"); // last frame is now content
// after
builder.AddAttribute(0, "onclick", handler);
builder.SetUpdatesAttributeName("value");
builder.AddContent(1, "Click"); Defensive patterns
Strategy: validation
Validate before calling
// Guard before calling
if (lastFrameType != RenderTreeFrameType.Attribute)
throw new InvalidOperationException("Last frame must be Attribute.");
builder.SetUpdatesAttributeName(name); Type guard
static bool LastFrameIsAttribute(RenderTreeFrameType t) => t == RenderTreeFrameType.Attribute;
Prevention
- Reorder emission so the tagged Attribute frame is immediately preceding.
- Don't interleave content/element frames between the attribute and SetUpdatesAttributeName.
When it happens
Trigger: Calling SetUpdatesAttributeName after OpenElement, AddContent, CloseElement, or any non-attribute Append. Pipeline/ordering bugs in custom RenderTreeBuilder code or generated emitters.
Common situations: Tree builders that interleave content frames between the handler attribute and the SetUpdatesAttributeName call. Buggy source generators / Razor compilation. Test fakes that don't track frame order.
Related errors
- Attributes may only be added immediately after frames of…
- No preceding attribute frame exists.
- Named events may only be added as children of frames of type
- The component type must implement
- The event handler parameter type
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/340b3eb4aae983b5.
Report an issue: GitHub.
Appendix: source
Thrown at src/Components/Components/src/Rendering/RenderTreeBuilder.cs:483
/// </para>
/// <para>
/// This information is used by the rendering system to determine whether
/// to accept a value update for the other attribute when receiving a
/// call to the event handler.
/// </para>
/// </summary>
/// <param name="updatesAttributeName">The name of another attribute whose value can be updated when the event handler is executed.</param>
public void SetUpdatesAttributeName(string updatesAttributeName)
{
if (_entries.Count == 0)
{
throw new InvalidOperationException("No preceding attribute frame exists.");
}
ref var prevFrame = ref _entries.Buffer[_entries.Count - 1];
if (prevFrame.FrameTypeField != RenderTreeFrameType.Attribute)
{
throw new InvalidOperationException($"Incorrect frame type: '{prevFrame.FrameTypeField}'");
}
prevFrame.AttributeEventUpdatesAttributeNameField = updatesAttributeName;
}
/// <summary>
/// Appends a frame representing a child component.
/// </summary>
/// <typeparam name="TComponent">The type of the child component.</typeparam>
/// <param name="sequence">An integer that represents the position of the instruction in the source code.</param>
public void OpenComponent<[DynamicallyAccessedMembers(Component)] TComponent>(int sequence) where TComponent : notnull, IComponent
=> OpenComponentUnchecked(sequence, typeof(TComponent));
/// <summary>
/// Appends a frame representing a child component.
/// </summary>
/// <param name="sequence">An integer that represents the position of the instruction in the source code.</param>
/// <param name="componentType">The type of the child component.</param>View on GitHub (pinned to 3600ca084e)