{"record":{"id":"3f334702e602f35d","repo":"stride3d/stride","slug":"container-s-value-is-null","errorCode":null,"errorMessage":"Container's value is null","messagePattern":"Container's value is null","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Quantum/MemberNode.cs","lineNumber":64,"sourceCode":"\n    /// <inheritdoc/>\n    public event EventHandler<INodeChangeEventArgs>? PrepareChange;\n\n    /// <inheritdoc/>\n    public event EventHandler<INodeChangeEventArgs>? FinalizeChange;\n\n    /// <inheritdoc/>\n    public event EventHandler<MemberNodeChangeEventArgs>? ValueChanging;\n\n    /// <inheritdoc/>\n    public event EventHandler<MemberNodeChangeEventArgs>? ValueChanged;\n\n    /// <inheritdoc/>\n    protected sealed override object? Value\n    {\n        get\n        {\n            var container = Parent.Retrieve() ?? throw new InvalidOperationException(\"Container's value is null\");\n            return MemberDescriptor.Get(container);\n        }\n    }\n\n    /// <inheritdoc/>\n    public void Update(object? newValue)\n    {\n        Update(newValue, true);\n    }\n\n    /// <summary>\n    /// Raises the <see cref=\"ValueChanging\"/> event with the given parameters.\n    /// </summary>\n    /// <param name=\"args\">The arguments of the event.</param>\n    protected void NotifyContentChanging(MemberNodeChangeEventArgs args)\n    {\n        PrepareChange?.Invoke(this, args);\n        ValueChanging?.Invoke(this, args);","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Quantum/MemberNode.cs#L46-L82","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check Parent.Retrieve() for null before reading the member node's Value, and skip/refresh if null.","Rebuild or refresh the graph node after reassigning or restoring the container object instead of reusing stale member nodes.","Wrap the Value read in try-catch for InvalidOperationException when reading during disposal/undo-redo transitions.","Verify the object graph: ensure the parent object is constructed and assigned before resolving its members."],"exampleFix":"// before\nvar value = memberNode.Value;\n// after\nif (memberNode.Parent.Retrieve() is { } container)\n{\n    var value = memberNode.Value;\n}\nelse\n{\n    // container is null (object disposed/reset) - refresh the graph or skip\n}","handlingStrategy":"validation","validationCode":"// C#\nif (memberNode.Parent.Retrieve() == null)\n    return; // container is null, cannot resolve member value\nvar value = memberNode.Value;","typeGuard":"static bool HasContainer(IMemberNode node) => node.Parent?.Retrieve() != null;","tryCatchPattern":"try { var value = memberNode.Value; }\ncatch (InvalidOperationException ex) when (ex.Message == \"Container's value is null\") { /* container gone: refresh or skip */ }","preventionTips":["Always check Parent.Retrieve() for null before reading member values","Do not cache IMemberNode references across model object replacements","Unsubscribe from node events before nulling/disposing the container object","Rebuild the graph after major object graph mutations"],"tags":["null-reference","graph-node","invalid-state","stride-quantum"],"backgroundTag":"null-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"}