stride3d/stride · error · NotSupportedException

Unsupported type for GetElementCount

Error message

Unsupported type for GetElementCount: {symbol}

What it means

GetElementCount is a SPIR-V builder extension method that computes the number of scalar elements a SymbolType holds (scalar=1, vector=its size, matrix=rows*columns). It throws NotSupportedException for any other SymbolType (e.g. array, struct, image, pointer types) because an element count is not defined for them.

Solutions

  1. Inspect the SymbolType before calling; only numeric types (scalar/vector/matrix) have an element count.
  2. For arrays, use the array element count (Size * GetElementCount(elementType)) instead; for structs, sum member counts.
  3. Add a match arm or a type guard in the calling code to route non-numeric types to the correct handling.
  4. Log/dump the offending symbol type to confirm which shader construct produced it.

Example fix

// before
int count = symbolType.GetElementCount();
// after
int count = symbolType switch
{
    ScalarType or VectorType or MatrixType => symbolType.GetElementCount(),
    ArrayType a => a.Size * a.BaseType.GetElementCount(),
    _ => throw new NotSupportedException($"Cannot compute element count for {symbolType}")
};
Defensive patterns

Strategy: type-guard

Validate before calling

bool hasElementCount = t is ScalarType or VectorType or MatrixType;

Type guard

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

Try / catch

try { count = symbol.GetElementCount(); } catch (NotSupportedException ex) { /* fallback: handle composite types separately */ }

Prevention

When it happens

Trigger: Calling GetElementCount() on a SymbolType that is not ScalarType, VectorType, or MatrixType — e.g. an ArrayType, StructType, PointerType, or ImageType passed to an instruction-size helper during SPIR-V emission.

Common situations: Compiling a shader that passes arrays or structs (or handles to buffers/images) into code paths that assume numeric types, e.g. composite construction, constant folding, or implicit conversion logic in the Stride shader compiler.

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/9c7ff0cf828224ff. Report an issue: GitHub.

Appendix: source

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

    public static SymbolType GetValueType(this SymbolType type)
    {
        return type switch
        {
            PointerType pointerType => pointerType.BaseType,
            _ => type
        };
    }

    public static SymbolType GetVectorOrScalar(this ScalarType scalar, int size)
        => size == 1 ? scalar : new VectorType(scalar, size);

    public static int GetElementCount(this SymbolType symbol) => symbol switch
    {
        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 };

View on GitHub (pinned to 96fad776d2)