stride3d/stride · error · NotSupportedException

Unsupported type for WithElementType

Error message

Unsupported type for WithElementType: {symbol}

What it means

WithElementType rebuilds a SymbolType with a new scalar element type (returns a new scalar, or a vector/matrix with the base type replaced). It throws NotSupportedException for SymbolTypes without an element type — arrays, structs, pointers, images, etc.

Solutions

  1. Ensure the caller only invokes WithElementType on Scalar/Vector/Matrix types.
  2. Add an ArrayType arm (rebuild array with new element base type) if arrays should be supported.
  3. Narrow the call site with a type check before rewriting the type.
  4. Inspect the failing symbol's kind to identify which new type variant needs handling.

Example fix

// before
var newType = symbolType.WithElementType(ScalarType.Float);
// after
var newType = symbolType switch
{
    ScalarType => (SymbolType)ScalarType.Float,
    VectorType v => v with { BaseType = ScalarType.Float },
    MatrixType m => m with { BaseType = ScalarType.Float },
    _ => throw new NotSupportedException($"Cannot replace element type of {symbolType}")
};
Defensive patterns

Strategy: type-guard

Validate before calling

bool canRewrite = t is ScalarType or VectorType or MatrixType;

Type guard

static bool SupportsElementTypeRewrite(SymbolType t) => t is ScalarType or VectorType or MatrixType;

Try / catch

try { newType = symbol.WithElementType(scalar); } catch (NotSupportedException) { /* use type-specific rewrite */ }

Prevention

When it happens

Trigger: Calling WithElementType() on a non-numeric SymbolType while rewriting types, e.g. during numeric type promotion/demotion or implicit conversion insertion in SPIR-V building.

Common situations: Shader code containing arrays/structs reaches a numeric-type rewrite helper that only understands scalar/vector/matrix, often after a language or IR change introduced new SymbolType kinds.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs:742

    {
        ScalarType s => 1,
        VectorType v => v.Size,
        MatrixType m => m.Rows * m.Columns,
        _ => throw new NotSupportedException($"Unsupported type for GetElementCount: {symbol}"),
    };
    public static ScalarType GetElementType(this SymbolType symbol) => symbol switch
    {
        ScalarType s => s,
        VectorType v => v.BaseType,
        MatrixType m => m.BaseType,
        _ => throw new NotSupportedException($"Unsupported type for GetElementType: {symbol}"),
    };
    public static SymbolType WithElementType(this SymbolType symbol, ScalarType elementType) => symbol switch
    {
        ScalarType s => elementType,
        VectorType v => v.BaseType == elementType ? v : v with { BaseType = elementType },
        MatrixType m => m.BaseType == elementType ? m : m with { BaseType = elementType },
        _ => throw new NotSupportedException($"Unsupported type for WithElementType: {symbol}"),
    };
    public static bool IsSignedInteger(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.Int or Scalar.Int64 };
    public static bool IsUnsignedInteger(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.UInt or Scalar.UInt64 };
    public static bool IsFloating(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.Half or Scalar.Float or Scalar.Double };
    public static bool IsInteger(this SymbolType symbol) => symbol.IsSignedInteger() || symbol.IsUnsignedInteger();
    public static bool IsNumber(this SymbolType symbol) => symbol.IsInteger() || symbol.IsFloating();
    public static bool IsSigned(this SymbolType symbol) => symbol.IsSignedInteger() || symbol.IsFloating();
    public static bool IsUnsigned(this SymbolType symbol) => symbol.IsUnsignedInteger();
    public static bool IsSignedIntegerVector(this SymbolType symbol)
        => symbol.IsSignedInteger() || symbol is VectorType v && v.BaseType.IsSignedInteger();
    public static bool IsUnsignedIntegerVector(this SymbolType symbol)
        => symbol.IsUnsignedInteger() || symbol is VectorType v && v.BaseType.IsUnsignedInteger();
    public static bool IsIntegerVector(this SymbolType symbol)
        => symbol.IsInteger() || symbol is VectorType v && v.BaseType.IsInteger();
    public static bool IsFloatingVector(this SymbolType symbol)
        => symbol.IsFloating() || symbol is VectorType v && v.BaseType.IsFloating();
    public static bool IsNumberVector(this SymbolType symbol)
        => symbol.IsNumber() || symbol is VectorType v && v.BaseType.IsNumber();

View on GitHub (pinned to 96fad776d2)