dotnet/aspnetcore · error · InvalidOperationException

More than one sibling of element '{frame.ElementNameField}'

Error message

More than one sibling of element '{frame.ElementNameField}' has the same key value, '{key}'. Key values must be unique.

What it means

Blazor uses @key to track element instances across re-renders for efficient DOM diffing. When RenderTreeDiffBuilder detects two sibling HTML elements (e.g., <div>, <li>) with the same non-null key value, it throws InvalidOperationException. The element name and key value are included in the message to aid debugging. Keys must be unique among siblings of the same parent.

Source

Thrown at src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs:383

                    result[key] = new KeyedItemInfo(existingEntry.OldIndex, newStartIndex);
                }
            }

            newStartIndex = NextSiblingIndex(frame, newStartIndex);
        }

        return result;
    }

    private static void ThrowExceptionForDuplicateKey(object key, in RenderTreeFrame frame)
    {
        switch (frame.FrameTypeField)
        {
            case RenderTreeFrameType.Component:
                throw new InvalidOperationException($"More than one sibling of component '{frame.ComponentTypeField}' has the same key value, '{key}'. Key values must be unique.");

            case RenderTreeFrameType.Element:
                throw new InvalidOperationException($"More than one sibling of element '{frame.ElementNameField}' has the same key value, '{key}'. Key values must be unique.");

            default:
                throw new InvalidOperationException($"More than one sibling has the same key value, '{key}'. Key values must be unique.");
        }
    }

    private static object KeyValue(ref RenderTreeFrame frame)
    {
        switch (frame.FrameTypeField)
        {
            case RenderTreeFrameType.Element:
                return frame.ElementKeyField;
            case RenderTreeFrameType.Component:
                return frame.ComponentKeyField;
            default:
                return null;
        }
    }

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Bind @key to a unique identifier for each item (database primary key, GUID, or composite key).
  2. Verify the keyed property has no duplicates in the data source.
  3. Use a composite key string if no single field is unique: key="$"{item.A}-{item.B}"."
  4. Remove @key if stable identity is not required.

Example fix

<!-- before -->
@foreach (var item in items)
{
    <li key="item.Type">@item.Name</li> <!-- Type repeats -->
}

<!-- after -->
@foreach (var item in items)
{
    <li key="item.Id">@item.Name</li>
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate key uniqueness for element lists
static void AssertUniqueElementKeys<T>(IEnumerable<T> items, Func<T, object> keySelector)
{
    var seen = new HashSet<object>();
    foreach (var item in items)
    {
        var key = keySelector(item);
        if (key != null && !seen.Add(key))
            throw new InvalidOperationException($"Duplicate element key: {key}");
    }
}

Prevention

When it happens

Trigger: Rendering a list of HTML elements where @key is set to a duplicated value. For example: foreach (var row in Rows) { <tr key="row.Status"><td>...</td></tr> } where Status is not unique. Also triggered by hardcoded keys on repeated elements.

Common situations: Keying list items by a non-unique field; using a constant key on all items; data with duplicate identifiers; using array index as key when items can be reordered (indices collide conceptually, though technically indices are unique, reordering causes remapping issues—not this specific error).

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/b532cae48b104a93. Report an issue: GitHub.