stride3d/stride · error · InvalidOperationException

An ObjectNode value cannot be modified after it has been…

Error message

An ObjectNode value cannot be modified after it has been constructed

What it means

Thrown by ObjectNode.UpdateFromMember when it receives a value update routed through NodeIndex.Empty. ObjectNode represents the root object itself, not a member; a member-style update addressed with an empty index would mean overwriting the whole already-constructed object value, which the quantum graph forbids — content changes must go through member/item nodes, not by replacing the object node's value.

Solutions

  1. Do not call UpdateFromMember with NodeIndex.Empty: this internal pathway is only for member-driven updates of child nodes; use the node's SetValue/Update pathway to change the root object node's value.
  2. Route root-level value changes through the node container/graph APIs designed for them.
  3. Treat this as an internal invariant violation: audit callers that pass the empty index and fix them to pass the member's actual NodeIndex.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at sources/presentation/Stride.Core.Quantum/ObjectNode.cs:185 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

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

        else if (Descriptor is DictionaryDescriptor dictionaryDescriptor)
        {
            dictionaryDescriptor.Remove(value, itemIndexValue);
        }
        else
        {
            throw new NotSupportedException("Unable to set the node value, the collection is unsupported");
        }

        UpdateReferences();
        NotifyItemChanged(args);
    }

    /// <inheritdoc/>
    protected internal override void UpdateFromMember(object newValue, NodeIndex index)
    {
        if (index == NodeIndex.Empty)
        {
            throw new InvalidOperationException("An ObjectNode value cannot be modified after it has been constructed");
        }
        Update(newValue, index, true);
    }

    protected void SetValue(object newValue)
    {
        value = newValue;
    }

    protected void NotifyItemChanging(ItemChangeEventArgs args)
    {
        PrepareChange?.Invoke(this, args);
        ItemChanging?.Invoke(this, args);
    }

    protected void NotifyItemChanged(ItemChangeEventArgs args)
    {
        ItemChanged?.Invoke(this, args);

View on GitHub (pinned to 96fad776d2)