stride3d/stride · error · InvalidOperationException

SetDescriptor should not call function 'RemoveAt'.

Error message

SetDescriptor should not call function 'RemoveAt'.

What it means

SetDescriptor.RemoveAt mirrors Insert: sets have no positional elements, so removal by index is impossible. The descriptor deliberately throws InvalidOperationException to signal that index-based removal was invoked on an unordered set. Use Remove with the actual key/item instead.

Solutions

  1. Call Remove(object set, object key) with the item itself instead of RemoveAt
  2. Guard with `if (descriptor is SetDescriptor)` before using positional APIs
  3. Switch to a list-backed type if index-based removal is genuinely required

Example fix

// before
descriptor.RemoveAt(mySet, 2);
// after
descriptor.Remove(mySet, itemToRemove);
Defensive patterns

Strategy: validation

Validate before calling

if (descriptor is SetDescriptor)
    descriptor.Remove(set, item);
else
    descriptor.RemoveAt(set, index);

Type guard

bool IsSetDescriptor(object d) => d is SetDescriptor;

Prevention

When it happens

Trigger: Calling SetDescriptor.RemoveAt(set, index) directly, or generic list-style collection manipulation code applying RemoveAt to a set descriptor.

Common situations: Shared collection-editing UI or serializer code paths that assume IList semantics; refactored code that switched a property from List<T> to HashSet<T> without updating index-based edits.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/e71a4376bc02ed4b. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core.Reflection/TypeDescriptors/SetDescriptor.cs:108

    public override void Insert(object set, int index, object? value)
    {
        throw new InvalidOperationException("SetDescriptor should not call function 'Insert'.");
    }

    /// <summary>
    /// Remove a value from a set
    /// </summary>
    /// <param name="set">The set.</param>
    /// <param name="key">The key.</param>
    public override void Remove(object set, object? key)
    {
        ArgumentNullException.ThrowIfNull(set);
        removeMethod.Invoke(set, key);
    }

    public override void RemoveAt(object set, int index)
    {
        throw new InvalidOperationException($"{nameof(SetDescriptor)} should not call function 'RemoveAt'.");
    }

    /// <summary>
    /// Clears the specified set.
    /// </summary>
    /// <param name="set">The set.</param>
    public override void Clear(object set)
    {
        clearMethod.Invoke(set);
    }

    /// <summary>
    /// Indicate whether the set contains the given value
    /// </summary>
    /// <param name="set">The set.</param>
    /// <param name="value">The value.</param>
    public bool Contains(object set, object? value)
    {

View on GitHub (pinned to 96fad776d2)