{"record":{"id":"76e549c4858ae42f","repo":"stride3d/stride","slug":"not-enough-generic-parameters-specified-when-instantiating","errorCode":null,"errorMessage":"Not enough generic parameters specified when instantiating {classSource.ToClassNameWithGenerics()}","messagePattern":"Not enough generic parameters specified when instantiating (.+?)","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs","lineNumber":152,"sourceCode":"public partial class SpirvBuilder\n{\n    public static void BuildInheritanceListWithoutSelf(IExternalShaderLoader shaderLoader, SpirvContext topLevelContext, ShaderClassInstantiation classSource, ReadOnlySpan<ShaderMacro> macros, SpirvContext declaringContext, List<ShaderClassInstantiation> inheritanceList, ResolveStep resolveStep)\n    {\n        // Build shader name mapping and collect generic parameter expressions\n        var shaderMapping = new Dictionary<int, ShaderClassInstantiation>();\n        // Map generic parameter index → resolved expression from classSource\n        ConstantExpression[]? resolvedGenericArgs = null;\n        string? declaringClassName = null;\n        // Also build import-level resolution: map shader name → its import's generic args (as expressions)\n        // Used to resolve GenericParamExpr that reference parent shaders' generics\n        var importArgsByName = new Dictionary<string, ConstantExpression[]>();\n\n        foreach (var i in declaringContext)\n        {\n            if (i.Op == Op.OpGenericParameterSDSL && (OpGenericParameterSDSL)i is { } genericParameter)\n            {\n                if (genericParameter.Index >= classSource.GenericArguments.Length)\n                    throw new NotImplementedException($\"Not enough generic parameters specified when instantiating {classSource.ToClassNameWithGenerics()}\");\n                resolvedGenericArgs ??= classSource.GenericArguments;\n                declaringClassName ??= genericParameter.DeclaringClass;\n            }\n            if (i.Op == Op.OpImportShaderSDSL && (OpImportShaderSDSL)i is { } importShader)\n            {\n                var shaderClassSource = ConvertToShaderClassSource(declaringContext, importShader);\n                shaderMapping[importShader.ResultId] = shaderClassSource;\n                if (shaderClassSource.GenericArguments.Length > 0)\n                    importArgsByName[importShader.ShaderName] = shaderClassSource.GenericArguments;\n            }\n        }\n\n        ConstantExpression ResolveGenericArg(ConstantExpression arg)\n        {\n            // First substitute the current shader's own generics\n            if (resolvedGenericArgs != null && declaringClassName != null)\n                arg = arg.Substitute(declaringClassName, resolvedGenericArgs);\n            // Then resolve any remaining GenericParamExpr by looking up parent imports","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs#L134-L170","documentation":"While walking the declaring context, an OpGenericParameterSDSL instruction refers to a generic parameter index that is not covered by the generic arguments supplied on the shader instantiation (classSource.GenericArguments). BuildInheritanceListWithoutSelf throws NotImplementedException because the shader class expects more generic parameters than the caller provided.","triggerScenarios":"Instantiating (e.g. via ShaderClassSource with generics, or a mixin import) a shader whose body declares OpGenericParameterSDSL with Index >= number of supplied generic arguments.","commonSituations":"Writing `MyShader<>` or `MyShader<float>` in SDSL while the shader (or a parent it inherits) declares two or more generic parameters; copying an instantiation that omitted arguments after a shader gained an extra generic parameter.","solutions":["Supply all required generic arguments at the instantiation site, e.g. `MyShader<float, float2>` matching the shader's declared generic parameter count.","Check the shader (and every shader it inherits/mixes) for OpGenericParameterSDSL declarations and count them against your argument list.","Give the generic parameter a default value in the shader source if it should be optional."],"exampleFix":"// before (SDSL)\nvar x = new MyShader<float>();\n// after\nvar x = new MyShader<float, float2>();","handlingStrategy":"validation","validationCode":"int declaredGenericCount = /* count OpGenericParameterSDSL in declaring context */;\nif (classSource.GenericArguments.Length < declaredGenericCount)\n    throw new ArgumentException($\"{classSource.ClassName} needs {declaredGenericCount} generic args, got {classSource.GenericArguments.Length}\");","typeGuard":null,"tryCatchPattern":"try { builder.BuildInheritanceList(...); }\ncatch (NotImplementedException ex) { throw new ShaderCompilationException($\"Fix generics at instantiation: {ex.Message}\", ex); }","preventionTips":["Match the number of `<...>` arguments to the shader's declared generic parameters","Re-check instantiation sites after adding a generic parameter to a shader","Use default generic values in SDSL where appropriate"],"tags":["spirv","generics","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}