stride3d/stride · error · NotImplementedException
Not enough generic parameters specified when instantiating
Error message
Not enough generic parameters specified when instantiating {classSource.ToClassNameWithGenerics()} What it means
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.
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.
Example fix
// before (SDSL) var x = new MyShader<float>(); // after var x = new MyShader<float, float2>();
Defensive patterns
Strategy: validation
Validate before calling
int declaredGenericCount = /* count OpGenericParameterSDSL in declaring context */;
if (classSource.GenericArguments.Length < declaredGenericCount)
throw new ArgumentException($"{classSource.ClassName} needs {declaredGenericCount} generic args, got {classSource.GenericArguments.Length}"); Try / catch
try { builder.BuildInheritanceList(...); }
catch (NotImplementedException ex) { throw new ShaderCompilationException($"Fix generics at instantiation: {ex.Message}", ex); } Prevention
- 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
When it happens
Trigger: Instantiating (e.g. via ShaderClassSource with generics, or a mixin import) a shader whose body declares OpGenericParameterSDSL with Index >= number of supplied generic arguments.
Common situations: 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.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Exception of type 'System.NotImplementedException' was…
- During mix phase, shaders generics are expected to be fully…
- Generic argument ( ) for could not be resolved during mix…
- Can't process constant
- Could not resolve generic arguments
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/76e549c4858ae42f.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs:152
public partial class SpirvBuilder
{
public static void BuildInheritanceListWithoutSelf(IExternalShaderLoader shaderLoader, SpirvContext topLevelContext, ShaderClassInstantiation classSource, ReadOnlySpan<ShaderMacro> macros, SpirvContext declaringContext, List<ShaderClassInstantiation> inheritanceList, ResolveStep resolveStep)
{
// Build shader name mapping and collect generic parameter expressions
var shaderMapping = new Dictionary<int, ShaderClassInstantiation>();
// Map generic parameter index → resolved expression from classSource
ConstantExpression[]? resolvedGenericArgs = null;
string? declaringClassName = null;
// Also build import-level resolution: map shader name → its import's generic args (as expressions)
// Used to resolve GenericParamExpr that reference parent shaders' generics
var importArgsByName = new Dictionary<string, ConstantExpression[]>();
foreach (var i in declaringContext)
{
if (i.Op == Op.OpGenericParameterSDSL && (OpGenericParameterSDSL)i is { } genericParameter)
{
if (genericParameter.Index >= classSource.GenericArguments.Length)
throw new NotImplementedException($"Not enough generic parameters specified when instantiating {classSource.ToClassNameWithGenerics()}");
resolvedGenericArgs ??= classSource.GenericArguments;
declaringClassName ??= genericParameter.DeclaringClass;
}
if (i.Op == Op.OpImportShaderSDSL && (OpImportShaderSDSL)i is { } importShader)
{
var shaderClassSource = ConvertToShaderClassSource(declaringContext, importShader);
shaderMapping[importShader.ResultId] = shaderClassSource;
if (shaderClassSource.GenericArguments.Length > 0)
importArgsByName[importShader.ShaderName] = shaderClassSource.GenericArguments;
}
}
ConstantExpression ResolveGenericArg(ConstantExpression arg)
{
// First substitute the current shader's own generics
if (resolvedGenericArgs != null && declaringClassName != null)
arg = arg.Substitute(declaringClassName, resolvedGenericArgs);
// Then resolve any remaining GenericParamExpr by looking up parent importsView on GitHub (pinned to 96fad776d2)