dotnet/aspnetcore · error · ArgumentException

The {nameof(frame.FrameType)} must be {RenderTreeFrameType.A

Error message

The {nameof(frame.FrameType)} must be {RenderTreeFrameType.Attribute}.

What it means

AddAttribute(int sequence, RenderTreeFrame frame) was called with a frame whose FrameTypeField is not Attribute. The overload accepts a raw frame and validates it is an attribute frame; anything else (Element, Component, etc.) is an ArgumentException.

Source

Thrown at src/Components/Components/src/Rendering/RenderTreeBuilder.cs:428

            AssertCanAddAttribute();
        }
    }

    /// <summary>
    /// <para>
    /// Appends a frame representing an attribute.
    /// </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="frame">A <see cref="RenderTreeFrame"/> holding the name and value of the attribute.</param>
    public void AddAttribute(int sequence, RenderTreeFrame frame)
    {
        if (frame.FrameTypeField != RenderTreeFrameType.Attribute)
        {
            throw new ArgumentException($"The {nameof(frame.FrameType)} must be {RenderTreeFrameType.Attribute}.");
        }

        AssertCanAddAttribute();
        frame.SequenceField = sequence;
        _entries.Append(frame);
    }

    /// <summary>
    /// Adds frames representing multiple attributes with the same sequence number.
    /// </summary>
    /// <param name="sequence">An integer that represents the position of the instruction in the source code.</param>
    /// <param name="attributes">A collection of key-value pairs representing attributes.</param>
    public void AddMultipleAttributes(int sequence, IEnumerable<KeyValuePair<string, object>>? attributes)
    {
        // Calling this up-front just to make sure we validate before mutating anything.
        AssertCanAddAttribute();

        if (attributes != null)

View on GitHub (pinned to 3600ca084e)

Solutions

  1. Check frame.FrameType == RenderTreeFrameType.Attribute before calling AddAttribute(seq, frame).
  2. Construct attribute frames via RenderTreeFrame.Attribute(...) factory rather than hand-built structs.
  3. If forwarding from another tree, filter by FrameType first.

Example fix

// before
builder.AddAttribute(0, someFrame); // someFrame.FrameType may be Element

// after
if (someFrame.FrameTypeField == RenderTreeFrameType.Attribute)
{
    builder.AddAttribute(0, someFrame);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (frame.FrameTypeField != RenderTreeFrameType.Attribute)
    throw new ArgumentException("Frame must be an Attribute frame.");
builder.AddAttribute(seq, frame);

Type guard

static bool IsAttributeFrame(in RenderTreeFrame f) => f.FrameTypeField == RenderTreeFrameType.Attribute;

Prevention

When it happens

Trigger: Passing an arbitrary RenderTreeFrame retrieved from a tree walk into AddAttribute. Constructing a RenderTreeFrame manually with the wrong FrameType and forwarding it.

Common situations: Custom tree-manipulation utilities. Code that copies frames between builders and forwards the wrong slot. Misuse in tests/fakes.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/3a371a7dba75b8ce. Report an issue: GitHub.