stride3d/stride · error · InvalidOperationException

SetDescriptor should not call function 'GetValue' with int…

Error message

SetDescriptor should not call function 'GetValue' with int index parameter.

What it means

Sets are unordered, so GetValue(set, int index) has no meaningful implementation in SetDescriptor. The method throws unconditionally as an API-contract guard: element access on a set must use the overload that takes the item/key, not an index.

Solutions

  1. Enumerate the set directly (foreach / IEnumerable) instead of indexed access
  2. Use the GetValue overload that accepts the item/key reference
  3. Special-case SetDescriptor in generic collection-rendering code

Example fix

// before
var item = descriptor.GetValue(mySet, i);
// after
foreach (var item in (IEnumerable)mySet) { ... }
Defensive patterns

Strategy: validation

Validate before calling

object GetItem(object set, object descriptor, int index)
{
    if (descriptor is SetDescriptor)
        return ((IEnumerable)set).Cast<object>().ElementAtOrDefault(index);
    return ((CollectionDescriptor)descriptor).GetValue(set, index);
}

Type guard

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

Try / catch

try { item = descriptor.GetValue(set, i); }
catch (InvalidOperationException) { item = ((IEnumerable)set).Cast<object>().Skip(i).FirstOrDefault(); }

Prevention

When it happens

Trigger: Calling SetDescriptor.GetValue(set, i) directly, or generic code that enumerates descriptor indices (e.g. for i in 0..Count) and calls GetValue(set, i).

Common situations: Inspectors/debuggers rendering collections positionally; code shared with ListDescriptor that reads elements by index.

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/ea561ae79a22b247. Report an issue: GitHub.

Appendix: source

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

    /// <summary>
    /// Get set value by index
    /// </summary>
    /// <param name="set">The set.</param>
    /// <param name="index">Index of value.</param>
    /// <returns></returns>
    public override object? GetValue(object set, object index)
    {
        return Contains(set, index) ? index : null;
    }

    /// <summary>
    /// Returns the value matching the given index in the set.
    /// </summary>
    /// <param name="set">The set.</param>
    /// <param name="index">The index.</param>
    public override object GetValue(object set, int index)
    {
        throw new InvalidOperationException("SetDescriptor should not call function 'GetValue' with int index parameter.");
    }

    /// <summary>
    /// Set the set value by index
    /// </summary>
    /// <param name="set">The set.</param>
    /// <param name="index">Index of value.</param>
    /// <returns></returns>
    public override void SetValue(object set, object index, object? value)
    {
        ArgumentNullException.ThrowIfNull(set);

        if (Contains(set, index))
        {
            Remove(set, index);
        }
        if (!Contains(set, value))
        {

View on GitHub (pinned to 96fad776d2)