{"record":{"id":"6172bb311fec998a","repo":"stride3d/stride","slug":"an-objectnode-cannot-contain-an-objectreference","errorCode":null,"errorMessage":"An ObjectNode cannot contain an ObjectReference","messagePattern":"An ObjectNode cannot contain an ObjectReference","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Quantum/ObjectNode.cs","lineNumber":25,"sourceCode":"using Stride.Core.Quantum.References;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace Stride.Core.Quantum;\n\n/// <summary>\n/// An implementation of <see cref=\"IGraphNode\"/> that gives access to an object or a boxed struct.\n/// </summary>\n/// <remarks>This content is not serialized by default.</remarks>\npublic class ObjectNode : GraphNodeBase, IInitializingObjectNode, IGraphNodeInternal\n{\n    private readonly HybridDictionary<string, IMemberNode> childrenMap = [];\n    private object value;\n\n    public ObjectNode(INodeBuilder nodeBuilder, object value, Guid guid, ITypeDescriptor descriptor, IReference? reference)\n        : base(nodeBuilder.SafeArgument().NodeContainer, guid, descriptor)\n    {\n        if (reference is ObjectReference)\n            throw new ArgumentException($\"An {nameof(ObjectNode)} cannot contain an {nameof(ObjectReference)}\");\n        this.value = value;\n        ItemReferences = reference as ReferenceEnumerable;\n    }\n\n    /// <inheritdoc/>\n    public IMemberNode this[string name] => childrenMap[name];\n\n    /// <inheritdoc/>\n    public IReadOnlyCollection<IMemberNode> Members => (IReadOnlyCollection<IMemberNode>)childrenMap.Values;\n\n    /// <inheritdoc/>\n    public IEnumerable<NodeIndex>? Indices => GetIndices();\n\n    /// <inheritdoc/>\n    [MemberNotNullWhen(true, nameof(Indices))]\n    public bool IsEnumerable => Descriptor is CollectionBaseDescriptor;\n\n    /// <inheritdoc/>","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Quantum/ObjectNode.cs#L7-L43","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Do not pass an ObjectReference for the reference parameter; pass null or a ReferenceEnumerable for collection item references","Store the target node reference on the containing node's ItemReferences (a ReferenceEnumerable) instead of on the ObjectNode itself","Build nodes through the standard NodeContainer / INodeBuilder CreateObjectNode path rather than calling the constructor directly","If you need a node that holds a reference, that is what item references on the parent node are for — restructure the graph accordingly"],"exampleFix":"// before\nvar node = new ObjectNode(builder, value, guid, descriptor, objectReference);\n// after\nvar node = new ObjectNode(builder, value, guid, descriptor, null);\nparent.SetItemReference(itemIndex, objectReference); // references live on the parent's ItemReferences","handlingStrategy":"validation","validationCode":"if (reference is ObjectReference) throw new InvalidOperationException(\"Pass ObjectReference via the parent's ItemReferences, not the ObjectNode constructor\");","typeGuard":"static bool IsValidNodeReference(IReference? r) => r is null or ReferenceEnumerable;","tryCatchPattern":"try { var node = new ObjectNode(builder, value, guid, desc, reference); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"cannot contain an ObjectReference\"))\n{ /* rebuild with null reference and attach the ObjectReference to the parent */ }","preventionTips":["Build nodes via NodeContainer/INodeBuilder instead of calling constructors directly","Keep ObjectReference attached to parent ItemReferences, never to ObjectNode itself","Type-check IReference implementations before passing them into node APIs"],"tags":["csharp","quantum","node-graph","constructor"],"backgroundTag":"invalid-constructor-argument","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"}