stride3d/stride · error · ArgumentNullException
registeredBuilders
Error message
registeredBuilders
What it means
The ShaderMixinContext constructor throws ArgumentNullException("registeredBuilders") when the dictionary mapping shader names to IShaderMixinBuilder instances is null. Without this registry the context cannot resolve mixin builders by name. This is a fail-fast constructor guard.
Solutions
- Pass a non-null dictionary (use ShaderMixinManager.RegisteredBuilders or an empty Dictionary<string, IShaderMixinBuilder>)
- Ensure the registry is initialized before context construction
- Use ShaderMixinManager.Register to populate builders rather than a hand-rolled null dictionary
Example fix
// before var ctx = new ShaderMixinContext(tree, parameters, lazyRegistry?.Value); // may be null // after var builders = lazyRegistry?.Value ?? new Dictionary<string, IShaderMixinBuilder>(); var ctx = new ShaderMixinContext(tree, parameters, builders);
Defensive patterns
Strategy: validation
Validate before calling
if (registeredBuilders is null) registeredBuilders = new Dictionary<string, IShaderMixinBuilder>();
Type guard
static bool HasBuilderRegistry(Dictionary<string, IShaderMixinBuilder> b) => b != null;
Try / catch
try { var ctx = new ShaderMixinContext(tree, parameters, builders); }
catch (ArgumentNullException ex) when (ex.ParamName == "registeredBuilders") { throw new InvalidOperationException("Builder registry must be initialized", ex); } Prevention
- Prefer ShaderMixinManager.RegisteredBuilders as the shared registry
- Initialize the registry dictionary at application startup
- Avoid lazily-populated registries passed before initialization
When it happens
Trigger: Calling new ShaderMixinContext(mixinTree, compilerParameters, null) — e.g. when building a fresh registry asynchronously and passing it before initialization, or when aDI/lookup returned null.
Common situations: Custom compiler hosts that forget to register builder dictionaries; passing a variable that is populated only later (race with initialization).
Related errors
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/b115055c2e4df156.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Effects/ShaderMixinContext.cs:44
private readonly ShaderMixinSource currentMixinSourceTree;
/// <summary>
/// Initializes a new instance of the <see cref="ShaderMixinContext" /> class.
/// </summary>
/// <param name="mixinTree">The mixin tree.</param>
/// <param name="compilerParameters">The default property container.</param>
/// <param name="registeredBuilders">The registered builders.</param>
/// <exception cref="System.ArgumentNullException">compilerParameters
/// or
/// registeredBuilders</exception>
public ShaderMixinContext(ShaderMixinSource mixinTree, ParameterCollection compilerParameters, Dictionary<string, IShaderMixinBuilder> registeredBuilders)
{
if (mixinTree == null) throw new ArgumentNullException("mixinTree");
if (compilerParameters == null)
throw new ArgumentNullException("compilerParameters");
if (registeredBuilders == null)
throw new ArgumentNullException("registeredBuilders");
// TODO: use a copy of the compilerParameters?
this.currentMixinSourceTree = mixinTree;
this.compilerParameters = compilerParameters;
this.registeredBuilders = registeredBuilders;
this.parameterCollections = new Stack<ParameterCollection>();
}
/// <summary>
/// Gets or sets the child effect.
/// </summary>
/// <value>The child effect.</value>
public string ChildEffectName { get; set; }
/// <summary>
/// Pushes the current parameters collection being used.
/// </summary>
/// <typeparam name="T">Type of the parameter collection</typeparam>View on GitHub (pinned to 96fad776d2)