stride3d/stride · error · InvalidOperationException
During mix phase, shaders generics are expected to be fully…
Error message
During mix phase, shaders generics are expected to be fully resolved
What it means
ValidateGenericParameters enforces that by the Mix resolve step every generic parameter is marked Resolved. If any genericParameters entry still has Resolved == false during mixing, the library throws InvalidOperationException — mixing cannot proceed with unresolved generics because names and constants would be ambiguous.
Solutions
- Ensure the instantiation supplies concrete constant values for all generics before the mix phase.
- Check that every shader referenced in generic expressions is imported so Substitute/ResolveGenericArg can resolve them.
- Run the resolve step (ResolveStep.Compile) before mixing so generic parameters get marked Resolved.
Example fix
// before BuildInheritanceListIncludingSelf(loader, ctx, source, macros, list, ResolveStep.Mix); // after (resolve first, then mix) BuildInheritanceListIncludingSelf(loader, ctx, source, macros, list, ResolveStep.Compile); BuildInheritanceListIncludingSelf(loader, ctx, source, macros, list, ResolveStep.Mix);
Defensive patterns
Strategy: validation
Validate before calling
if (resolveStep == ResolveStep.Mix && genericParameters.Any(p => !p.Resolved))
throw new InvalidOperationException($"Unresolved generics before mix: {string.Join(",", genericParameters.Where(p => !p.Resolved).Select(p => p.Name))}"); Type guard
bool AllResolved(IEnumerable<GenericParameter> ps) => ps.All(p => p.Resolved);
Try / catch
try { ValidateGenericParameters(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("fully resolved")) { /* rerun the resolve pass before mixing */ } Prevention
- Always run a resolve (Compile) pass before the mix phase
- Ensure all shaders referenced inside generic expressions are imported
- Assert generic resolution immediately after each resolve step in tests
When it happens
Trigger: Running the mixin/mix phase (ResolveStep.Mix) when a generic argument failed to substitute earlier — e.g. a GenericParamExpr that referenced a parent's generic not present in importArgsByName, or an argument that never got a constant value.
Common situations: Inheriting from a parameterized mixin whose generic arguments themselves reference generics of an unimported shader; an instantiation that skipped the earlier resolve pass; a bug where resolution silently failed and returned the expression unresolved.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Generic argument ( ) for could not be resolved during mix…
- Not enough generic parameters specified when instantiating
- Exception of type 'System.NotImplementedException' was…
- Can't process constant
- IsObjectReference returned true for an object that is not…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/347ae7c0f8b87b58.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs:372
var constantBuffer = expr.EmitToBuffer();
context.RemoveAt(instructionIndex);
var bound = context.Bound;
context.InsertWithoutDuplicates(ref instructionIndex, genericParameter.ResultId, constantBuffer);
context.Bound = bound;
return true;
}
public override void ValidateGenericParameters(string classNameWithGenerics, List<GenericParameter> genericParameters)
{
// Fully resolved?
if (resolveStep == ResolveStep.Mix)
{
if (!genericParameters.All(x => x.Resolved))
{
throw new InvalidOperationException("During mix phase, shaders generics are expected to be fully resolved");
}
}
}
public override void PostProcess(string classNameWithGenerics)
{
if (resolveStep == ResolveStep.Mix)
{
classSource.ClassName = classNameWithGenerics;
classSource.GenericArguments = [];
}
}
}
private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, string classNameWithGenerics, GenericResolver genericResolver, IExternalShaderLoader shaderLoader, ReadOnlySpan<ShaderMacro> macros)
{
var resolvedLinks = new Dictionary<int, string>();
var semantics = new Dictionary<string, string>();View on GitHub (pinned to 96fad776d2)