dotnet/aspnetcore · error · InvalidOperationException
No preceding attribute frame exists.
Error message
No preceding attribute frame exists.
What it means
RenderTreeBuilder.SetUpdatesAttributeName annotates the most recently appended frame as an event handler whose execution updates a specific attribute. It requires at least one frame to have been added (_entries.Count > 0). If called when no frames exist at all, it throws InvalidOperationException. This typically indicates the method was called before any content was added to the builder.
Source
Thrown at src/Components/Components/src/Rendering/RenderTreeBuilder.cs:477
}
/// <summary>
/// <para>
/// Indicates that the preceding attribute represents an event handler
/// whose execution updates the attribute with name <paramref name="updatesAttributeName"/>.
/// </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));View on GitHub (pinned to 294cab2f9b)
Solutions
- Ensure at least one frame (typically an event handler attribute frame) has been added before calling SetUpdatesAttributeName.
- Call SetUpdatesAttributeName immediately after the attribute it annotates, not before any frames exist.
- Review the call ordering: OpenElement -> AddAttribute (event handler) -> SetUpdatesAttributeName -> CloseElement.
- If this is from generated code, check that the @bind directive is placed on a valid element with a preceding attribute.
Example fix
// before
builder.SetUpdatesAttributeName("value"); // no frames yet -> throws
builder.OpenElement(0, "input");
// after
builder.OpenElement(0, "input");
builder.AddAttribute(1, "oninput", handler);
builder.SetUpdatesAttributeName("value"); // annotates the oninput frame Defensive patterns
Strategy: validation
Validate before calling
// The builder checks _entries.Count == 0; guard before calling // No public API to check this; ensure correct call ordering in your code // Always add at least one frame (an attribute) before calling SetUpdatesAttributeName
Prevention
- Call SetUpdatesAttributeName only after adding an event handler attribute frame.
- Maintain strict ordering: OpenElement -> AddAttribute (handler) -> SetUpdatesAttributeName -> CloseElement.
- In generated code, ensure source generators emit SetUpdatesAttributeName at the correct position.
- Add unit tests for render fragments that exercise the SetUpdatesAttributeName path.
When it happens
Trigger: Calling builder.SetUpdatesAttributeName("value") as the first operation on a fresh RenderTreeBuilder, or after the builder's buffer has been cleared/reset. This is generated by the Razor compiler for @bind directives and is rarely called manually, but can be triggered by incorrect manual RenderTreeBuilder code.
Common situations: Incorrect manual RenderTreeBuilder sequencing; code generated by a custom source generator that emits SetUpdatesAttributeName in the wrong position; calling SetUpdatesAttributeName after CloseElement/CloseComponent cleared the context.
Related errors
- Incorrect frame type: '{prevFrame.FrameTypeField}'
- Valueless attributes may only be added immediately after fra
- The FrameType must be Attribute.
- Cannot set a key outside the scope of a component or element
- Cannot set a key on a frame of type {parentFrame.FrameTypeFi
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/73c7f13184b20ef7.
Report an issue: GitHub.