stride3d/stride · error · ArgumentException

An ObjectNode cannot contain an ObjectReference

Error message

An ObjectNode cannot contain an ObjectReference

What it means

The ObjectNode constructor rejects a reference parameter that is itself an ObjectReference, because an ObjectNode represents a single object value and an ObjectReference is meant to live only on item references of another node. Passing one is a misuse of the node-builder API and indicates the caller confused node types. The library throws ArgumentException immediately to keep the node graph consistent.

Solutions

  1. Do not pass an ObjectReference for the reference parameter; pass null or a ReferenceEnumerable for collection item references
  2. Store the target node reference on the containing node's ItemReferences (a ReferenceEnumerable) instead of on the ObjectNode itself
  3. Build nodes through the standard NodeContainer / INodeBuilder CreateObjectNode path rather than calling the constructor directly
  4. If you need a node that holds a reference, that is what item references on the parent node are for — restructure the graph accordingly

Example fix

// before
var node = new ObjectNode(builder, value, guid, descriptor, objectReference);
// after
var node = new ObjectNode(builder, value, guid, descriptor, null);
parent.SetItemReference(itemIndex, objectReference); // references live on the parent's ItemReferences
Defensive patterns

Strategy: validation

Validate before calling

if (reference is ObjectReference) throw new InvalidOperationException("Pass ObjectReference via the parent's ItemReferences, not the ObjectNode constructor");

Type guard

static bool IsValidNodeReference(IReference? r) => r is null or ReferenceEnumerable;

Try / catch

try { var node = new ObjectNode(builder, value, guid, desc, reference); }
catch (ArgumentException ex) when (ex.Message.Contains("cannot contain an ObjectReference"))
{ /* rebuild with null reference and attach the ObjectReference to the parent */ }

Prevention

When it happens

Trigger: Constructing an ObjectNode directly (or via a custom INodeBuilder) and passing an IReference that is actually an ObjectReference instance in the 'reference' parameter; building nodes manually instead of through NodeContainer/Create APIs.

Common situations: Custom node builders or graph-serialization code that stores an ObjectReference against what should be an ObjectNode; refactoring that swapped ObjectNode and ObjectNode-with-references semantics; hand-rolled NodeContainer replacement.

Related errors


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

Appendix: source

Thrown at sources/presentation/Stride.Core.Quantum/ObjectNode.cs:25

using Stride.Core.Quantum.References;
using System.Diagnostics.CodeAnalysis;

namespace Stride.Core.Quantum;

/// <summary>
/// An implementation of <see cref="IGraphNode"/> that gives access to an object or a boxed struct.
/// </summary>
/// <remarks>This content is not serialized by default.</remarks>
public class ObjectNode : GraphNodeBase, IInitializingObjectNode, IGraphNodeInternal
{
    private readonly HybridDictionary<string, IMemberNode> childrenMap = [];
    private object value;

    public ObjectNode(INodeBuilder nodeBuilder, object value, Guid guid, ITypeDescriptor descriptor, IReference? reference)
        : base(nodeBuilder.SafeArgument().NodeContainer, guid, descriptor)
    {
        if (reference is ObjectReference)
            throw new ArgumentException($"An {nameof(ObjectNode)} cannot contain an {nameof(ObjectReference)}");
        this.value = value;
        ItemReferences = reference as ReferenceEnumerable;
    }

    /// <inheritdoc/>
    public IMemberNode this[string name] => childrenMap[name];

    /// <inheritdoc/>
    public IReadOnlyCollection<IMemberNode> Members => (IReadOnlyCollection<IMemberNode>)childrenMap.Values;

    /// <inheritdoc/>
    public IEnumerable<NodeIndex>? Indices => GetIndices();

    /// <inheritdoc/>
    [MemberNotNullWhen(true, nameof(Indices))]
    public bool IsEnumerable => Descriptor is CollectionBaseDescriptor;

    /// <inheritdoc/>

View on GitHub (pinned to 96fad776d2)