{"record":{"id":"815a4e4c2e5034ce","repo":"stride3d/stride","slug":"cannot-clone-mixin-name-from-a-null-parent","errorCode":null,"errorMessage":"Cannot clone mixin [{Name}] from a null parent","messagePattern":"Cannot clone mixin \\[(.+?)\\] from a null parent","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders/ShaderMixinSource.cs","lineNumber":115,"sourceCode":"        /// <summary>\n        /// Adds a macro to this mixin.\n        /// </summary>\n        /// <param name=\"name\">The name.</param>\n        /// <param name=\"value\">The value.</param>\n        public void AddMacro(string name, object value)\n        {\n            Macros.Add(new ShaderMacro(name, value));\n        }\n\n        /// <summary>\n        /// Clones from the specified <see cref=\"ShaderMixinSource\"/>.\n        /// </summary>\n        /// <param name=\"parent\">The parent mixin to clone from.</param>\n        /// <exception cref=\"System.ArgumentNullException\">parent</exception>\n        public void CloneFrom(ShaderMixinSource parent)\n        {\n            if (parent == null)\n                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\");","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders/ShaderMixinSource.cs#L97-L133","documentation":"CloneFrom throws an ArgumentNullException (with this message) when the parent ShaderMixinSource argument is null. Cloning requires a source mixin to copy Mixins, Macros, and Compositions from, so a null parent is rejected with the receiving mixin's Name embedded for diagnosis. Called by ApplyShader and Mixin.","triggerScenarios":"ShaderMixinSource.CloneFrom(null) is invoked directly, or indirectly via Mixin/ApplyShader when the shader source being mixed in resolved to null (e.g. a dictionary lookup or composition map returned null for the requested shader).","commonSituations":"A shader key/family name that doesn't exist in the shader source registry so the lookup returns null and is passed to CloneFrom; uninitialized composition dictionaries; refactoring that removed an earlier null check on the mixin parameter.","solutions":["Fix the upstream lookup that produced the null parent: verify the shader name/key exists in the source registry before calling Mixin/ApplyShader.","Add a null guard in the caller so an unresolved shader source is logged and skipped instead of reaching CloneFrom.","If intentionally having no parent, don't call CloneFrom — construct/populate the ShaderMixinSource directly."],"exampleFix":"// before\nshaderSource.Mixin(mixinName); // resolves to null parent\n// after\nvar parent = shaderRegistry.Find(mixinName);\nif (parent == null)\n    throw new InvalidOperationException($\"Unknown shader mixin '{mixinName}'\");\nshaderSource.CloneFrom(parent);","handlingStrategy":"type-guard","validationCode":"if (parent == null)\n    throw new InvalidOperationException(\"Cannot clone mixin: parent shader source was not found — check the shader name/registry\");","typeGuard":"bool TryCloneFrom(ShaderMixinSource target, ShaderMixinSource? parent)\n{\n    if (parent is null) return false;\n    target.CloneFrom(parent);\n    return true;\n}","tryCatchPattern":"try { source.CloneFrom(parent); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"parent\")\n{\n    // log which mixin resolved to null and fall back to a default shader source\n}","preventionTips":["Null-check results from shader registry lookups before mixing them in.","Make Mixin/ApplyShader callers validate the resolved shader source exists.","Keep shader name constants in one place to avoid typos yielding null lookups."],"tags":["null-reference","shader-mixin","argument-validation"],"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"}