stride3d/stride · error · ArgumentException

A NodeIndex instance cannot be passed as the value of…

Error message

A NodeIndex instance cannot be passed as the value of another NodeIndex instance.

What it means

NodeIndex is a struct wrapping an object Value used to index items in collection nodes. Wrapping an existing NodeIndex inside another NodeIndex would box one index into another, producing a nonsensical nested index. The constructor throws ArgumentException as a sanity check against this misuse.

Solutions

  1. Use the NodeIndex instance directly instead of wrapping it in a new NodeIndex.
  2. Unwrap first: use the inner index's Value (new NodeIndex(existingIndex.Value)) only if you truly need a copy — but prefer reusing the instance.
  3. For multi-dimensional access, resolve the parent item node and index that node, rather than nesting indexes.
  4. Inspect object-typed variables holding keys and ensure NodeIndex instances are not double-wrapped when converting to index form.

Example fix

// before
var index = new NodeIndex(existingIndex);
// after
var index = existingIndex; // NodeIndex.Empty checks and comparisons work on the instance directly
Defensive patterns

Strategy: validation

Validate before calling

// C#
if (value is NodeIndex existing)
    return existing; // reuse instead of wrapping
var index = new NodeIndex(value);

Type guard

static bool IsNestedIndex(object? value) => value is NodeIndex;

Try / catch

try { var index = new NodeIndex(value); }
catch (ArgumentException ex) when (ex.Message.Contains("NodeIndex")) { /* value already an index: use it directly */ }

Prevention

When it happens

Trigger: new NodeIndex(someNodeIndex) — passing a NodeIndex (or an object that statically was NodeIndex) as the value, typically when index values flow through object-typed variables or generic APIs.

Common situations: Generic dictionary/collection code where the key is already a NodeIndex stored as object; composing multi-level indexes by accident instead of using the intended nested-item lookup (accessing the item node then indexing it again).

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at sources/presentation/Stride.Core.Quantum/NodeIndex.cs:30

{
    /// <summary>
    /// An index that is null.
    /// </summary>
    public static readonly NodeIndex Empty = new();

    /// <summary>
    /// The value of the index.
    /// </summary>
    public readonly object? Value;

    /// <summary>
    /// Initializes a new instance of the <see cref="NodeIndex"/> structure.
    /// </summary>
    /// <param name="value">The value of the index.</param>
    public NodeIndex(object? value) : this()
    {
        // Sanity check, to avoid boxing index into index
        if (value is NodeIndex) throw new ArgumentException($"A {nameof(NodeIndex)} instance cannot be passed as the value of another {nameof(NodeIndex)} instance.");
        Value = value;
    }

    /// <summary>
    /// Gets whether this index is empty.
    /// </summary>
    public readonly bool IsEmpty => Value is null;

    /// <summary>
    /// Gets whether this index is an integer.
    /// </summary>
    public readonly bool IsInt => Value is int;

    /// <summary>
    /// Gets the integer value of this index.
    /// </summary>
    /// <exception cref="InvalidCastException">The value of this index is not an integer.</exception>
    public readonly int Int => Value is int i ? i : throw new InvalidCastException();

View on GitHub (pinned to 96fad776d2)