stride3d/stride · error · ArgumentNullException
Blendmap parameter cannot be null for a child layer
Error message
Blendmap parameter cannot be null for a child layer
What it means
MaterialGeneratorContext.PushLayer builds the blend-layer tree during shader generation. Every layer except the top-level one must know how it blends with its parent, so if a child layer is pushed with a null blendMap it throws ArgumentNullException for the blendMap parameter.
Solutions
- Pass a non-null blend map (e.g. an IMaterialBlendLayer with a valid blending operation) when pushing child layers
- Restructure so only the top-level layer is pushed without a blend map
- Set the blending in your MaterialBlendLayer (e.g. opacity/multiply/add) before PushLayer
- If a child should inherit without blending, use a default blend map like opaque/multiply instead of null
Example fix
// before: child layer without blend map
context.PushLayer(childLayer, null); // throws when nested
// after: supply a blend map for child layers
context.PushLayer(childLayer, new MaterialBlendLayer(context, blendMap) { BlendMap = blendMap }); Defensive patterns
Strategy: validation
Validate before calling
if (context.CurrentLayer != null && blendMap == null)
blendMap = new MaterialBlendMap(); // or supply an explicit blend operation
context.PushLayer(layer, blendMap); Type guard
bool NeedsBlendMap(MaterialGeneratorContext ctx) => ctx.CurrentLayer != null;
Try / catch
try { context.PushLayer(layer, blendMap); }
catch (ArgumentNullException ex)
{
logger.LogError(ex, "Child layer pushed without blend map");
context.PushLayer(layer, defaultBlendMap);
} Prevention
- Always assign a blending operation to nested material layers
- Only the top-level layer may omit the blend map
- Review custom material descriptors for nested PushLayer calls during code review
When it happens
Trigger: Calling PushLayer(null) when another layer is already open (currentLayerContext != null) — i.e. pushing a child/nested layer without specifying its blend map, typically from a custom material descriptor with nested material layers.
Common situations: Custom IMaterialDescriptor with nested layers forgetting to supply a blending operation (e.g. MaterialBlendLayer with null BlendLayers map); copying sample code but omitting the blend map for inner layers.
Related errors
- Cannot PopMaterial more than PushMaterial
- Cannot PopLayer when no balancing PushLayer was called
- Value cannot be null. (Parameter 'location')
- Value cannot be null. (Parameter 'asset')
- Value cannot be null. (Parameter 'value')
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/f3c8dc6d50375bba.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Rendering/Rendering/Materials/MaterialGeneratorContext.cs:215
{
throw new InvalidOperationException("Cannot PopMaterial more than PushMaterial");
}
return materialStack.Pop();
}
/// <summary>
/// Pushes a new layer with the specified blend map.
/// </summary>
/// <param name="blendMap">The blend map used by this layer.</param>
public void PushLayer(IComputeScalar blendMap)
{
if (Step != MaterialGeneratorStep.GenerateShader)
return;
// We require a blend layer expect for the top level one.
if (currentLayerContext != null && blendMap == null)
{
throw new ArgumentNullException(nameof(blendMap), "Blendmap parameter cannot be null for a child layer");
}
var newLayer = new MaterialBlendLayerContext(this, currentLayerContext, blendMap);
if (currentLayerContext != null)
{
currentLayerContext.Children.Add(newLayer);
}
currentLayerContext = newLayer;
}
/// <summary>
/// Pops the current layer.
/// </summary>
public void PopLayer()
{
if (Step != MaterialGeneratorStep.GenerateShader)
return;
View on GitHub (pinned to 96fad776d2)