{"record":{"id":"18826e7f47384e90","repo":"stride3d/stride","slug":"the-shading-model-with-type-shadingmodel-gettype-is-already","errorCode":null,"errorMessage":"The shading model with type [{shadingModel.GetType()}] is already added","messagePattern":"The shading model with type \\[(.+?)\\] is already added","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Rendering/Rendering/Materials/MaterialShadingModelCollection.cs","lineNumber":29,"sourceCode":"    /// <summary>\n    /// Stores a collection of shading model used by a layer and allow to compare if a layer can be blend by attributes (if\n    /// shading model doesn't change) or by shading (if shading model is different).\n    /// </summary>\n    internal sealed class MaterialShadingModelCollection : Dictionary<Type, (IMaterialShadingModelFeature ShadingModel, ShadingModelShaderBuilder ShaderBuilder)>\n    {\n        /// <summary>\n        /// Adds the specified shading model associated with source to this collection.\n        /// </summary>\n        /// <typeparam name=\"T\">Type of the shading model</typeparam>\n        /// <param name=\"shadingModel\">The shading model</param>\n        public ShadingModelShaderBuilder Add<T>(T shadingModel) where T : class, IMaterialShadingModelFeature\n        {\n            if (shadingModel == null) throw new ArgumentNullException(nameof(shadingModel));\n\n            // Check that we cannot have the same type of shading model multiple times\n            if (ContainsKey(shadingModel.GetType()))\n            {\n                throw new InvalidOperationException($\"The shading model with type [{shadingModel.GetType()}] is already added\");\n            }\n\n            var result = new ShadingModelShaderBuilder();\n            this[shadingModel.GetType()] = (shadingModel, result);\n            return result;\n        }\n\n        /// <summary>\n        /// Copies the shading models of this instance to the destination instance.\n        /// </summary>\n        /// <param name=\"node\">The destination collection</param>\n        public void CopyTo(MaterialShadingModelCollection node)\n        {\n            if (node == null) throw new ArgumentNullException(nameof(node));\n            foreach (var keyValue in this)\n            {\n                node[keyValue.Key] = keyValue.Value;\n            }","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Rendering/Rendering/Materials/MaterialShadingModelCollection.cs#L11-L47","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nmaterial.ShadingModelCollection.Add(pbr);\nmaterial.ShadingModelCollection.Add(pbr2); // throws: same type\n// after\nif (!material.ShadingModelCollection.ContainsKey(typeof(PBRShadingModel)))\n    material.ShadingModelCollection.Add(pbr);","handlingStrategy":"validation","validationCode":"if (material.ShadingModelCollection.ContainsKey(shadingModel.GetType()))\n    return; // or remove first","typeGuard":"static bool CanAdd(Material m, MaterialShadingModel sm) => !m.ShadingModelCollection.ContainsKey(sm.GetType());","tryCatchPattern":"try { material.ShadingModelCollection.Add(shadingModel); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"is already added\")) {\n    // already present: treat as idempotent\n}","preventionTips":["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"],"tags":["rendering","materials","duplicate-key"],"backgroundTag":"invalid-argument-value","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"}