{"record":{"id":"5966ef827a46cfe8","repo":"stride3d/stride","slug":"a-nodeindex-instance-cannot-be-passed-as-the-value-of","errorCode":null,"errorMessage":"A NodeIndex instance cannot be passed as the value of another NodeIndex instance.","messagePattern":"A NodeIndex instance cannot be passed as the value of another NodeIndex instance\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Quantum/NodeIndex.cs","lineNumber":30,"sourceCode":"{\n    /// <summary>\n    /// An index that is null.\n    /// </summary>\n    public static readonly NodeIndex Empty = new();\n\n    /// <summary>\n    /// The value of the index.\n    /// </summary>\n    public readonly object? Value;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"NodeIndex\"/> structure.\n    /// </summary>\n    /// <param name=\"value\">The value of the index.</param>\n    public NodeIndex(object? value) : this()\n    {\n        // Sanity check, to avoid boxing index into index\n        if (value is NodeIndex) throw new ArgumentException($\"A {nameof(NodeIndex)} instance cannot be passed as the value of another {nameof(NodeIndex)} instance.\");\n        Value = value;\n    }\n\n    /// <summary>\n    /// Gets whether this index is empty.\n    /// </summary>\n    public readonly bool IsEmpty => Value is null;\n\n    /// <summary>\n    /// Gets whether this index is an integer.\n    /// </summary>\n    public readonly bool IsInt => Value is int;\n\n    /// <summary>\n    /// Gets the integer value of this index.\n    /// </summary>\n    /// <exception cref=\"InvalidCastException\">The value of this index is not an integer.</exception>\n    public readonly int Int => Value is int i ? i : throw new InvalidCastException();","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Quantum/NodeIndex.cs#L12-L48","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Use the NodeIndex instance directly instead of wrapping it in a new NodeIndex.","Unwrap first: use the inner index's Value (new NodeIndex(existingIndex.Value)) only if you truly need a copy — but prefer reusing the instance.","For multi-dimensional access, resolve the parent item node and index that node, rather than nesting indexes.","Inspect object-typed variables holding keys and ensure NodeIndex instances are not double-wrapped when converting to index form."],"exampleFix":"// before\nvar index = new NodeIndex(existingIndex);\n// after\nvar index = existingIndex; // NodeIndex.Empty checks and comparisons work on the instance directly","handlingStrategy":"validation","validationCode":"// C#\nif (value is NodeIndex existing)\n    return existing; // reuse instead of wrapping\nvar index = new NodeIndex(value);","typeGuard":"static bool IsNestedIndex(object? value) => value is NodeIndex;","tryCatchPattern":"try { var index = new NodeIndex(value); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"NodeIndex\")) { /* value already an index: use it directly */ }","preventionTips":["Never wrap an existing NodeIndex in another NodeIndex; reuse the instance","When keys come from object-typed sources, check 'is NodeIndex' first","For nested collections, index the item node rather than composing indexes","Use NodeIndex.Empty instead of new NodeIndex(null) where possible"],"tags":["argument-validation","index","type-mismatch","stride-quantum"],"backgroundTag":"invalid-argument-value","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}