dotnet/aspnetcore · error · InvalidOperationException
Valueless attributes may only be added immediately after…
Error message
Valueless attributes may only be added immediately after frames of type {RenderTreeFrameType.Element} What it means
AddAttribute(int, string) (the valueless/bool-true overload) was called when the last non-attribute frame on the builder was not an Element. Valueless attributes like `@bind`-less boolean HTML attributes are only meaningful on elements, so the builder rejects attaching one to a component or at the root.
Solutions
- Ensure OpenElement(...) was the most recent non-attribute frame before calling AddAttribute(seq, name).
- If the attribute is for a component parameter, use AddComponentParameter or the typed AddAttribute overloads instead.
- Reorder builder calls so the valueless attribute follows the element opening.
Example fix
// before builder.AddAttribute(0, "readonly"); // no element open builder.OpenElement(1, "input"); // after builder.OpenElement(0, "input"); builder.AddAttribute(1, "readonly");
Defensive patterns
Strategy: validation
Validate before calling
// In custom builders, guard before valueless attribute
if (lastNonAttributeFrameType != RenderTreeFrameType.Element)
throw new InvalidOperationException("Open an element first.");
builder.AddAttribute(seq, name); Type guard
static bool CanAddValuelessAttribute(RenderTreeFrameType last) => last == RenderTreeFrameType.Element;
Prevention
- Call OpenElement before any valueless AddAttribute(seq, name).
- Prefer authoring via Razor, which emits the correct order automatically.
When it happens
Trigger: Calling builder.AddAttribute(seq, "disabled") before any OpenElement, or right after OpenComponent. Razor compiling an attribute on a component using a valueless Razor directive attribute syntax.
Common situations: Authoring custom component bases / manual RenderTreeBuilder code. Razor syntax that emits a valueless attribute against a component tag. Misordering builder calls.
Related errors
- The must be .
- Attributes may only be added immediately after frames of…
- No preceding attribute frame exists.
- The component type must implement
- Incorrect frame type
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/2259e206b02a8498.
Report an issue: GitHub.
Appendix: source
Thrown at src/Components/Components/src/Rendering/RenderTreeBuilder.cs:174
/// <param name="textContent">Content for the new text frame.</param>
public void AddContent(int sequence, object? textContent)
=> AddContent(sequence, textContent?.ToString());
/// <summary>
/// <para>
/// Appends a frame representing a bool-valued attribute with value 'true'.
/// </para>
/// <para>
/// The attribute is associated with the most recently added element.
/// </para>
/// </summary>
/// <param name="sequence">An integer that represents the position of the instruction in the source code.</param>
/// <param name="name">The name of the attribute.</param>
public void AddAttribute(int sequence, string name)
{
if (_lastNonAttributeFrameType != RenderTreeFrameType.Element)
{
throw new InvalidOperationException($"Valueless attributes may only be added immediately after frames of type {RenderTreeFrameType.Element}");
}
_entries.AppendAttribute(sequence, name, ElementBoolTrueValue);
}
/// <summary>
/// <para>
/// Appends a frame representing a bool-valued attribute.
/// </para>
/// <para>
/// The attribute is associated with the most recently added element. If the value is <c>false</c> and the
/// current element is not a component, the frame will be omitted.
/// </para>
/// </summary>
/// <param name="sequence">An integer that represents the position of the instruction in the source code.</param>
/// <param name="name">The name of the attribute.</param>
/// <param name="value">The value of the attribute.</param>
public void AddAttribute(int sequence, string name, bool value)View on GitHub (pinned to 3600ca084e)