stride3d/stride · error · NotSupportedException

Unsupported constant vector element type

Error message

Unsupported constant vector element type: {Values[0].GetType()}

What it means

ConstantVector.ToString() renders a SPIR-V constant vector back into SDSL source text. It only knows how to type float element values; any other element type (int, bool, double) hit the throw-all switch arm. The library throws NotSupportedException because printing a vector of that element type as SDSL is not implemented.

Solutions

  1. Use float-valued constant vectors (e.g. cast literals to float) when passing vectors as generic arguments.
  2. Extend the switch in ConstantVector.ToString() to map int => "int", uint => "uint", bool => "bool" etc., mirroring SDSL vector type names.
  3. If you own the input shader, replace the non-float vector generic with a float vector or a scalar constant.

Example fix

// before
var type = Values[0] switch
{
    float => "float",
    _ => throw new NotSupportedException(...),
};
// after
var type = Values[0] switch
{
    float => "float",
    int => "int",
    uint => "uint",
    bool => "bool",
    _ => throw new NotSupportedException($"Unsupported constant vector element type: {Values[0].GetType()}"),
};
Defensive patterns

Strategy: validation

Validate before calling

if (vector.Values.Length == 0 || vector.Values[0] is not float)
    throw new ArgumentException($"ConstantVector must be float-typed to stringify, got {vector.Values.FirstOrDefault()?.GetType()}");

Type guard

bool IsStringifiable(ConstantVector v) => v.Values is { Length: > 0 } && v.Values[0] is float;

Try / catch

try { text = vector.ToString(); }
catch (NotSupportedException ex) { text = $"<{ex.Message}>"; /* fall back to non-string form */ }

Prevention

When it happens

Trigger: Calling ToString() (directly or via ShaderClassInstantiation.ToClassNameWithGenerics / error messages / cache keys) on a ConstantVector whose Values[0] is not a float, e.g. an int or bool constant vector produced by TryGetConstantValue.

Common situations: A shader uses integer or boolean constant vectors (e.g. int2 coordinates, bool4 masks) as generic arguments; SDSL grammar/analysis produces a non-float constant vector which later gets stringified when building shader names or diagnostics.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/e3962b3f91bd6237. Report an issue: GitHub.

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs:126

                    hashCode = (hashCode * 397) ^ (current.GetHashCode());
            }

            return hashCode;
        }
    }
}

// Constant vector (generated by TryGetConstantValue)
public class ConstantVector
{
    public required object[] Values;

    public override string ToString()
    {
        var type = Values[0] switch
        {
            float => "float",
            _ => throw new NotSupportedException($"Unsupported constant vector element type: {Values[0].GetType()}"),
        };

        return $"{type}{Values.Length}({string.Join(",", Values)})";
    }
}


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

View on GitHub (pinned to 96fad776d2)