stride3d/stride · error · InvalidOperationException

Container's value is null

Error message

Container's value is null

What it means

MemberNode.Value reads its value by calling Parent.Retrieve() to get the container (owning object) and then reflects the member off it. This error means the parent container's value is null — the owning object has been disposed, reset, or was never assigned — so the member cannot be resolved. Stride.Core.Quantum throws InvalidOperationException because asking for a member's value with no backing container is an invalid state, not a bad argument.

Solutions

  1. Check Parent.Retrieve() for null before reading the member node's Value, and skip/refresh if null.
  2. Rebuild or refresh the graph node after reassigning or restoring the container object instead of reusing stale member nodes.
  3. Wrap the Value read in try-catch for InvalidOperationException when reading during disposal/undo-redo transitions.
  4. Verify the object graph: ensure the parent object is constructed and assigned before resolving its members.

Example fix

// before
var value = memberNode.Value;
// after
if (memberNode.Parent.Retrieve() is { } container)
{
    var value = memberNode.Value;
}
else
{
    // container is null (object disposed/reset) - refresh the graph or skip
}
Defensive patterns

Strategy: validation

Validate before calling

// C#
if (memberNode.Parent.Retrieve() == null)
    return; // container is null, cannot resolve member value
var value = memberNode.Value;

Type guard

static bool HasContainer(IMemberNode node) => node.Parent?.Retrieve() != null;

Try / catch

try { var value = memberNode.Value; }
catch (InvalidOperationException ex) when (ex.Message == "Container's value is null") { /* container gone: refresh or skip */ }

Prevention

When it happens

Trigger: Accessing Value (directly or via GetValue/Retrieve) on an IMemberNode whose parent node's Retrieve() returns null, e.g. after the root object is set to null, a node is detached, or the parent GraphNode was cleared while member nodes still exist.

Common situations: Holding onto a MemberNode reference after replacing/nulling the model object in an editor; observing nodes during disposal; subscribing to node changes and reading Value in a callback that fires after the container was nulled.

Related errors


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

Appendix: source

Thrown at sources/presentation/Stride.Core.Quantum/MemberNode.cs:64

    /// <inheritdoc/>
    public event EventHandler<INodeChangeEventArgs>? PrepareChange;

    /// <inheritdoc/>
    public event EventHandler<INodeChangeEventArgs>? FinalizeChange;

    /// <inheritdoc/>
    public event EventHandler<MemberNodeChangeEventArgs>? ValueChanging;

    /// <inheritdoc/>
    public event EventHandler<MemberNodeChangeEventArgs>? ValueChanged;

    /// <inheritdoc/>
    protected sealed override object? Value
    {
        get
        {
            var container = Parent.Retrieve() ?? throw new InvalidOperationException("Container's value is null");
            return MemberDescriptor.Get(container);
        }
    }

    /// <inheritdoc/>
    public void Update(object? newValue)
    {
        Update(newValue, true);
    }

    /// <summary>
    /// Raises the <see cref="ValueChanging"/> event with the given parameters.
    /// </summary>
    /// <param name="args">The arguments of the event.</param>
    protected void NotifyContentChanging(MemberNodeChangeEventArgs args)
    {
        PrepareChange?.Invoke(this, args);
        ValueChanging?.Invoke(this, args);

View on GitHub (pinned to 96fad776d2)