stride3d/stride · error · InvalidOperationException
The shading model with type
Error message
The shading model with type [{shadingModel.GetType()}] is already added What it means
MaterialShadingModelCollection is a keyed collection that stores at most one shading model per concrete type. Add throws InvalidOperationException when a shading model of the same runtime type is added twice, to prevent duplicate shader builders for the same shading model.
Solutions
- Check ShadingModelCollection.ContainsKey(typeof(T)) before calling Add, or just index the existing entry
- Remove the existing shading model of that type first if replacement is intended
- If multiple variants are needed, create distinct shading model subclasses instead of two instances of the same type
Example fix
// before
material.ShadingModelCollection.Add(pbr);
material.ShadingModelCollection.Add(pbr2); // throws: same type
// after
if (!material.ShadingModelCollection.ContainsKey(typeof(PBRShadingModel)))
material.ShadingModelCollection.Add(pbr); Defensive patterns
Strategy: validation
Validate before calling
if (material.ShadingModelCollection.ContainsKey(shadingModel.GetType()))
return; // or remove first Type guard
static bool CanAdd(Material m, MaterialShadingModel sm) => !m.ShadingModelCollection.ContainsKey(sm.GetType());
Try / catch
try { material.ShadingModelCollection.Add(shadingModel); }
catch (InvalidOperationException ex) when (ex.Message.Contains("is already added")) {
// already present: treat as idempotent
} Prevention
- Guard every Add with ContainsKey(shadingModel.GetType())
- Don't re-run material setup code on hot-reload without clearing first
- Use distinct subclasses when different shading model configurations are needed
When it happens
Trigger: Calling material.ShadingModelCollection.Add on a MaterialShadingModel instance whose type is already present in the collection, e.g. adding two instances of PBRShadingModel, or re-adding the same instance.
Common situations: Configuring a material in code and adding a shading model that the material already has (e.g. from a copied/cloned material or a constructor default); repeated setup code executed on material reload.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Asked for " + i + " but no more than 10 default textures…
- This method can only be called during step
- A scene matching the given
- A template provider with the same name has already been…
- A texture with size [ ] already exist with the same output…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/18826e7f47384e90.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Rendering/Rendering/Materials/MaterialShadingModelCollection.cs:29
/// <summary>
/// Stores a collection of shading model used by a layer and allow to compare if a layer can be blend by attributes (if
/// shading model doesn't change) or by shading (if shading model is different).
/// </summary>
internal sealed class MaterialShadingModelCollection : Dictionary<Type, (IMaterialShadingModelFeature ShadingModel, ShadingModelShaderBuilder ShaderBuilder)>
{
/// <summary>
/// Adds the specified shading model associated with source to this collection.
/// </summary>
/// <typeparam name="T">Type of the shading model</typeparam>
/// <param name="shadingModel">The shading model</param>
public ShadingModelShaderBuilder Add<T>(T shadingModel) where T : class, IMaterialShadingModelFeature
{
if (shadingModel == null) throw new ArgumentNullException(nameof(shadingModel));
// Check that we cannot have the same type of shading model multiple times
if (ContainsKey(shadingModel.GetType()))
{
throw new InvalidOperationException($"The shading model with type [{shadingModel.GetType()}] is already added");
}
var result = new ShadingModelShaderBuilder();
this[shadingModel.GetType()] = (shadingModel, result);
return result;
}
/// <summary>
/// Copies the shading models of this instance to the destination instance.
/// </summary>
/// <param name="node">The destination collection</param>
public void CopyTo(MaterialShadingModelCollection node)
{
if (node == null) throw new ArgumentNullException(nameof(node));
foreach (var keyValue in this)
{
node[keyValue.Key] = keyValue.Value;
}View on GitHub (pinned to 96fad776d2)