dotnet/aspnetcore · error · InvalidOperationException
No preceding attribute frame exists.
Error message
No preceding attribute frame exists.
What it means
SetUpdatesAttributeName was called when the builder has no frames yet (_entries.Count == 0). The method tags the most recently appended frame as one whose value should be refreshed when an event handler fires, so it requires a preceding Attribute frame to operate on.
Solutions
- Call AddAttribute(...) for the event-handler attribute before SetUpdatesAttributeName.
- Verify the builder has at least one frame and the previous frame is an Attribute before invoking.
- Restructure emission order so the update-target attribute precedes the SetUpdatesAttributeName call.
Example fix
// before
builder.SetUpdatesAttributeName("value");
builder.OpenElement(0, "input");
// after
builder.OpenElement(0, "input");
builder.AddAttribute(1, "oninput", handler);
builder.SetUpdatesAttributeName("value"); Defensive patterns
Strategy: validation
Validate before calling
// Guard in custom tree-build code
if (entries.Count == 0) throw new InvalidOperationException("Append an attribute first.");
builder.SetUpdatesAttributeName(name); Prevention
- Ensure an Attribute frame is appended before SetUpdatesAttributeName.
- Track entry count in custom builders and skip if empty.
When it happens
Trigger: Calling builder.SetUpdatesAttributeName(name) as the very first operation, or after Clear() with nothing re-appended. Misordered manual tree construction.
Common situations: Hand-written RenderTreeBuilder code that emits event-handler wiring. Custom Razor-emitted code generators that emit SetUpdatesAttributeName at the wrong point.
Related errors
- Incorrect frame type
- Attributes may only be added immediately after frames of…
- The component type must implement
- The must be .
- Valueless attributes may only be added immediately after…
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/73c7f13184b20ef7.
Report an issue: GitHub.
Appendix: 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 3600ca084e)