{"record":{"id":"2a1af2c36d1a75da","repo":"stride3d/stride","slug":"cannot-deep-clone-mixin-name-from-a-null-parent","errorCode":null,"errorMessage":"Cannot deep clone mixin [{Name}] from a null parent","messagePattern":"Cannot deep clone mixin \\[(.+?)\\] from a null parent","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders/ShaderMixinSource.cs","lineNumber":133,"sourceCode":"                throw new ArgumentNullException(\"parent\", $\"Cannot clone mixin [{Name}] from a null parent\");\n\n            Mixins.AddRange(parent.Mixins);\n            Macros.AddRange(parent.Macros);\n            foreach (var shaderBasic in parent.Compositions)\n            {\n                Compositions[shaderBasic.Key] = shaderBasic.Value;\n            }\n        }\n\n        /// <summary>\n        /// Clones from the specified <see cref=\"ShaderMixinSource\"/>. Clones members too.\n        /// </summary>\n        /// <param name=\"parent\">The parent mixin to clone from.</param>\n        /// <exception cref=\"System.ArgumentNullException\">parent</exception>\n        public void DeepCloneFrom(ShaderMixinSource parent)\n        {\n            if (parent == null)\n                throw new ArgumentNullException(\"parent\", $\"Cannot deep clone mixin [{Name}] from a null parent\");\n\n            foreach (var mixin in parent.Mixins)\n                Mixins.Add((ShaderClassCode)mixin.Clone());\n            Macros.AddRange(parent.Macros);\n            foreach (var shaderBasic in parent.Compositions)\n            {\n                Compositions[shaderBasic.Key] = (ShaderSource)shaderBasic.Value.Clone();\n            }\n        }\n\n        public override bool Equals(object against)\n        {\n            if (ReferenceEquals(null, against)) return false;\n            if (ReferenceEquals(this, against)) return true;\n            if (against.GetType() != this.GetType()) return false;\n            return Equals((ShaderMixinSource)against);\n        }\n","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders/ShaderMixinSource.cs#L115-L151","documentation":"DeepCloneFrom throws an ArgumentNullException (with this message) when the parent ShaderMixinSource is null. Deep cloning additionally clones each child ShaderClassCode mixin individually, so it likewise requires a non-null source. Called by Compile during shader compilation preparation.","triggerScenarios":"ShaderMixinSource.DeepCloneFrom(null) reached from Compile when the mixin source that Compile resolved (via a shader manager or effect compiler pass) was null — e.g. a requested shader family was never registered or was filtered out by the compiler.","commonSituations":"Compiling an effect whose ShaderSource was never attached/registered; a compiler pass (e.g. effect permutation resolution) yielding null for the mixin; tests that build a ShaderMixinSource but forget to initialize it before Compile.","solutions":["Ensure the shader family/mixins are registered in the shader source collection before Compile runs, so the parent passed to DeepCloneFrom is non-null.","Add a null check before Compile: if the mixin source is null, log the missing shader name and fail early with a clear message.","Inspect the effect compiler pipeline stage producing the null parent (breakpoint or log in DeepCloneFrom callers) and fix the resolution step."],"exampleFix":"// before\nvar mixin = new ShaderMixinSource();\ncompiler.Compile(mixin); // internally DeepCloneFrom(null)\n// after\nvar mixin = new ShaderMixinSource();\nmixin.Mixins.Add((ShaderClassCode)ShaderManager.Find(\"MyShader\")); // populate before compile\ncompiler.Compile(mixin);","handlingStrategy":"type-guard","validationCode":"if (parent == null || parent.Mixins.Count == 0)\n    throw new InvalidOperationException(\"Compile requires an initialized, non-null mixin source\");","typeGuard":"bool TryDeepClone(ShaderMixinSource target, ShaderMixinSource? parent)\n{\n    if (parent is null) return false;\n    target.DeepCloneFrom(parent);\n    return true;\n}","tryCatchPattern":"try { mixin.DeepCloneFrom(parent); compiler.Compile(...); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"parent\")\n{\n    // trace which compile stage passed a null mixin source and fix registration\n}","preventionTips":["Register shader families before invoking Compile on effects that reference them.","Assert the mixin source is populated (Mixins.Count > 0) in test fixtures before compiling.","Add compiler-pass logging so a null parent can be traced to the resolution stage that produced it."],"tags":["null-reference","shader-mixin","compilation"],"backgroundTag":"null-argument","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}