stride3d/stride · error · ArgumentNullException

Cannot clone mixin [ ] from a null parent

Error message

Cannot clone mixin [{Name}] from a null parent

What it means

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.

Solutions

  1. Fix the upstream lookup that produced the null parent: verify the shader name/key exists in the source registry before calling Mixin/ApplyShader.
  2. Add a null guard in the caller so an unresolved shader source is logged and skipped instead of reaching CloneFrom.
  3. If intentionally having no parent, don't call CloneFrom — construct/populate the ShaderMixinSource directly.

Example fix

// before
shaderSource.Mixin(mixinName); // resolves to null parent
// after
var parent = shaderRegistry.Find(mixinName);
if (parent == null)
    throw new InvalidOperationException($"Unknown shader mixin '{mixinName}'");
shaderSource.CloneFrom(parent);
Defensive patterns

Strategy: type-guard

Validate before calling

if (parent == null)
    throw new InvalidOperationException("Cannot clone mixin: parent shader source was not found — check the shader name/registry");

Type guard

bool TryCloneFrom(ShaderMixinSource target, ShaderMixinSource? parent)
{
    if (parent is null) return false;
    target.CloneFrom(parent);
    return true;
}

Try / catch

try { source.CloneFrom(parent); }
catch (ArgumentNullException ex) when (ex.ParamName == "parent")
{
    // log which mixin resolved to null and fall back to a default shader source
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders/ShaderMixinSource.cs:115

        /// <summary>
        /// Adds a macro to this mixin.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="value">The value.</param>
        public void AddMacro(string name, object value)
        {
            Macros.Add(new ShaderMacro(name, value));
        }

        /// <summary>
        /// Clones from the specified <see cref="ShaderMixinSource"/>.
        /// </summary>
        /// <param name="parent">The parent mixin to clone from.</param>
        /// <exception cref="System.ArgumentNullException">parent</exception>
        public void CloneFrom(ShaderMixinSource parent)
        {
            if (parent == null)
                throw new ArgumentNullException("parent", $"Cannot clone mixin [{Name}] from a null parent");

            Mixins.AddRange(parent.Mixins);
            Macros.AddRange(parent.Macros);
            foreach (var shaderBasic in parent.Compositions)
            {
                Compositions[shaderBasic.Key] = shaderBasic.Value;
            }
        }

        /// <summary>
        /// Clones from the specified <see cref="ShaderMixinSource"/>. Clones members too.
        /// </summary>
        /// <param name="parent">The parent mixin to clone from.</param>
        /// <exception cref="System.ArgumentNullException">parent</exception>
        public void DeepCloneFrom(ShaderMixinSource parent)
        {
            if (parent == null)
                throw new ArgumentNullException("parent", $"Cannot deep clone mixin [{Name}] from a null parent");

View on GitHub (pinned to 96fad776d2)