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
- Ensure the caller only invokes WithElementType on Scalar/Vector/Matrix types.
- Add an ArrayType arm (rebuild array with new element base type) if arrays should be supported.
- Narrow the call site with a type check before rewriting the type.
- 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
- Restrict numeric rewrites to numeric types
- Add match arms for arrays if rewrite should propagate into them
- Keep WithElementType/GetElementType/GetElementCount arms in sync
- Test type rewrites against every SymbolType subclass
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
- Cannot simplify constant of type
- Unsupported type for GetElementCount
- Unsupported type for GetElementType
- Unsupported constant type
- Unsupported base type
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)