dotnet/aspnetcore · error · InvalidOperationException
Attributes may only be added immediately after frames of…
Error message
Attributes may only be added immediately after frames of type {RenderTreeFrameType.Element} or {RenderTreeFrameType.Component} What it means
AssertCanAddAttribute threw because the most recent non-attribute frame was neither Element nor Component. Attributes/component parameters can only follow an element or component opening; adding them after content, region, ref capture, etc. is invalid.
Solutions
- Reorder so AddAttribute/AddComponentParameter immediately follows OpenElement/OpenComponent (or other attributes).
- In custom code, track the last non-attribute frame type and re-open a scope before adding attributes if needed.
- Use higher-level Razor/ComponentBase authoring instead of raw RenderTreeBuilder where possible.
Example fix
// before builder.OpenElement(0, "input"); builder.AddContent(1, "text"); builder.AddAttribute(2, "value", x); // last non-attr frame is now content // after builder.OpenElement(0, "input"); builder.AddAttribute(1, "value", x); builder.AddContent(2, "text");
Defensive patterns
Strategy: validation
Validate before calling
if (lastNonAttributeFrameType != RenderTreeFrameType.Element &&
lastNonAttributeFrameType != RenderTreeFrameType.Component)
throw new InvalidOperationException("Open an element/component before adding attributes.");
builder.AddAttribute(seq, name, value); Type guard
static bool CanAddAttributeAfter(RenderTreeFrameType last)
=> last == RenderTreeFrameType.Element || last == RenderTreeFrameType.Component; Prevention
- Add attributes/parameters immediately after OpenElement/OpenComponent.
- Avoid interleaving content/capture/region frames before attributes.
- Prefer Razor authoring over raw RenderTreeBuilder to get correct ordering.
When it happens
Trigger: Calling AddAttribute/AddComponentParameter after AddContent, after CloseElement, after a reference capture, or at the root. Any sequence where _lastNonAttributeFrameType drifted away from Element/Component before an attribute append.
Common situations: Misordered manual tree construction. Source generators emitting attributes in the wrong slot. Custom component bases that emit parameters conditionally and miss the ordering invariant.
Related errors
- Incorrect frame type
- Named events may only be added as children of frames of type
- No preceding attribute frame exists.
- 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/e0e69d8702d76d10.
Report an issue: GitHub.
Appendix: source
Thrown at src/Components/Components/src/Rendering/RenderTreeBuilder.cs:724
_lastNonAttributeFrameType = RenderTreeFrameType.Region;
}
/// <summary>
/// Marks a previously appended region frame as closed. Calls to this method
/// must be balanced with calls to <see cref="OpenRegion(int)"/>.
/// </summary>
public void CloseRegion()
{
var indexOfEntryBeingClosed = _openElementIndices.Pop();
_entries.Buffer[indexOfEntryBeingClosed].RegionSubtreeLengthField = _entries.Count - indexOfEntryBeingClosed;
}
private void AssertCanAddAttribute()
{
if (_lastNonAttributeFrameType != RenderTreeFrameType.Element
&& _lastNonAttributeFrameType != RenderTreeFrameType.Component)
{
throw new InvalidOperationException($"Attributes may only be added immediately after frames of type {RenderTreeFrameType.Element} or {RenderTreeFrameType.Component}");
}
}
private void AssertCanAddComponentParameter()
{
if (_lastNonAttributeFrameType != RenderTreeFrameType.Component)
{
throw new InvalidOperationException($"Component parameters may only be added immediately after frames of type {RenderTreeFrameType.Component}");
}
}
private int? GetCurrentParentFrameIndex()
=> _openElementIndices.Count == 0 ? (int?)null : _openElementIndices.Peek();
private RenderTreeFrameType? GetCurrentParentFrameType()
{
var parentIndex = GetCurrentParentFrameIndex();
return parentIndex.HasValueView on GitHub (pinned to 3600ca084e)