stride3d/stride · error · NotSupportedException
Unsupported type for element-wise cast
Error message
Unsupported type for element-wise cast: {valueType} What it means
Thrown by Builder.Expressions.Convert in the element-wise numeric cast phase. Before emitting conversion instructions it classifies valueType as a scalar or vector to decide how to apply the element type cast; any other composite type (e.g. a raw matrix reaching this code path) is unsupported and raises NotSupportedException.
Solutions
- Restructure the shader to cast per-row/per-column instead of casting the whole composite.
- Extend Builder.Expressions.cs to decompose MatrixType into vectors before the element-wise cast.
- Check the call site (ConvertTexCoord/ConvertOffset etc.) to see why a matrix reached the cast and fix the source types.
Example fix
// before (shader) int3x3 m = (int3x3)float3x3m; // after: cast rows individually int3 r0 = (int3)m[0]; int3 r1 = (int3)m[1]; int3 r2 = (int3)m[2];
Defensive patterns
Strategy: type-guard
Validate before calling
bool elementWiseCastSupported(SymbolType t) => t is ScalarType || t is VectorType;
Type guard
bool IsScalarOrVector(SymbolType t) => t is ScalarType || t is VectorType;
Try / catch
try { var r = builder.Convert(table, context, value, castType); }
catch (NotSupportedException e) { Log.Error(e.Message); /* fall back to per-component conversion */ } Prevention
- Only cast scalars and vectors element-wise; decompose matrices first.
- Avoid composite numeric retype casts in shaders.
- If you need matrix retype, cast each row/column separately.
When it happens
Trigger: Calling Convert where the intermediate valueType after expansion is neither ScalarType nor VectorType when reaching the element-wise cast switch (e.g. castType requiring element-wise conversion of a MatrixType).
Common situations: Casting composite shader values (matrix types) between base element types such as int<->float; typically surfaces from unusual shader constructs mixing matrices with numeric conversions.
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
- Unsupported composite type
- Unsupported type for location counting
- Type not supported in SPIR-V
- spirv_to_dxil_pipeline failed; SPIR-V dumped to
- Can't OpLoad with cbuffer
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/6183e72a39bc85ed.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs:608
{
values[i] = Insert(new OpVectorShuffle(context.GetOrRegister(new VectorType(m1.BaseType, m2.Rows)), context.Bound++, values[i], values[i], new(shuffleIndices))).ResultId;
}
}
valueType = new VectorType(m1.BaseType, m2.Rows);
valueCount = m2.Columns;
break;
}
}
if (valueType.GetElementType() != castType.GetElementType())
{
// Type casting
// (process each vector one by one)
(int elementSize, var castTypeSameSize) = valueType switch
{
ScalarType s => (1, (SymbolType)castType.GetElementType()),
VectorType s => (s.Size, new VectorType(castType.GetElementType(), s.Size)),
_ => throw new NotSupportedException($"Unsupported type for element-wise cast: {valueType}"),
};
for (int i = 0; i < valueCount; ++i)
{
var rowValue = values[i];
if (rowValue == 0)
throw new InvalidOperationException($"Type conversion from {originalType} to {castType} failed during conversion (current type: {valueType})");
var typeCasting = (valueType.GetElementType(), castType.GetElementType()) switch
{
// https://learn.microsoft.com/en-us/windows/win32/direct3d9/casting-and-conversion
(ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.Int }) => InsertData(new OpConvertFToS(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)),
(ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.UInt }) => InsertData(new OpConvertFToU(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)),
(ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpFOrdNotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeVectorRepeat(new FloatLiteral(new(32, true, true), 0.0, new()), elementSize).Id)),
(ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpINotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeVectorRepeat(new IntegerLiteral(new(32, false, true), 0, new()), elementSize).Id)),
(ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpINotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeVectorRepeat(new IntegerLiteral(new(32, false, false), 0, new()), elementSize).Id)),
(ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Float }) => InsertData(new OpConvertSToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)),View on GitHub (pinned to 96fad776d2)