stride3d/stride · error · NotSupportedException
Unsupported type in array binary operation
Error message
Unsupported type in array binary operation: {otherType} What it means
BinaryOperation on array-typed values applies the operation element-by-element. The 'other' operand must be an array of the same type (element extracted per index) or a scalar (broadcast). Any other type for the other operand triggers NotSupportedException.
Solutions
- Ensure both array operands have identical type and size, or use a scalar for broadcast
- Loop over elements explicitly in the shader instead of relying on array operators
- Cast or restructure one operand to match the other's array type
- Check that array element types match exactly (including signedness)
Example fix
// before (HLSL) float a[4]; float b[8]; var c = a + b; // after float a[4]; float b[4]; var c = a + b; // elementwise
Defensive patterns
Strategy: type-guard
Validate before calling
// Only allow array+same-array or array+scalar binary ops
if (left is ArrayType at && right is not (ArrayType aeq when aeq == at) && right is not ScalarType)
throw new ShaderSemanticException($"Cannot apply operator between array {left} and {right}"); Type guard
bool IsArrayOpCompatible(ArrayType a, SymbolType other) => other is ArrayType o && o == a || other is ScalarType;
Try / catch
try { var r = BinaryOperation(table, context, left, op, right, info); }
catch (NotSupportedException ex) when (ex.Message.StartsWith("Unsupported type in array binary operation")) { throw new ShaderSemanticException("Array binary operations require same-type arrays or scalar broadcast", ex); } Prevention
- Ensure both array operands match in element type and length
- Use explicit element loops for cross-size/mixed-type array math
- Prefer scalar broadcast over vector/array mixing
When it happens
Trigger: Binary operation between an array value and a mismatched type (different array type/size, struct, vector) where leftType is ArrayType.
Common situations: Adding arrays of different lengths or element types; mixing array and vector in shader math; generated code assuming implicit array broadcasting rules.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Type of binary operation could not be determined
- Unsupported type in struct binary operation
- 64bit integers
- Can't add type
- Can't cast between array of different sizes
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/2c51db7f0407aadd.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs:272
// Can indirectly happen inside struct (SDSL specific)
var arrayType = leftType as ArrayType ?? rightType as ArrayType;
if (arrayType != null)
{
var arrayValue = leftType is ArrayType ? left : right;
var otherType = leftType is ArrayType ? rightType : leftType;
var otherValue = leftType is ArrayType ? right : left;
Span<int> arrayValues = stackalloc int[arrayType.Size];
for (int i = 0; i < arrayType.Size; ++i)
{
var memberValue = Buffer.Insert(Position++, new OpCompositeExtract(context.GetOrRegister(arrayType.BaseType), context.Bound++, arrayValue.Id, [i])).ToValue();
var otherMemberValue = otherType switch
{
// If the other value is also a struct of same type, extract its value
ArrayType otherArrayType when otherArrayType == arrayType
=> Buffer.Insert(Position++, new OpCompositeExtract(context.GetOrRegister(arrayType.BaseType), context.Bound++, otherValue.Id, [i])).ToValue(),
ScalarType => otherValue,
_ => throw new NotSupportedException($"Unsupported type in array binary operation: {otherType}"),
};
arrayValues[i] = leftType is StructType
? BinaryOperation(table, context, memberValue, op, otherMemberValue, info, name).Id
: BinaryOperation(table, context, otherMemberValue, op, memberValue, info, name).Id;
}
return Buffer.Insert(Position++, new OpCompositeConstruct(context.GetOrRegister(arrayType), resultId, [.. arrayValues])).ToValue();
}
(var operandType, var resultType) = AnalyzeBinaryOperation(table, leftType, op, rightType, info) ?? throw new InvalidOperationException("Type of binary operation could not be determined");
// TODO: Some specific cases where one of the operands doesn't need to have exact same type as resultType (such as shift in OpShiftRightLogical, or signedness for some other operations)
// We'll need to review those cases
left = Convert(context, left, operandType);
right = Convert(context, right, operandType);
var resultTypeId = context.GetOrRegister(resultType);
View on GitHub (pinned to 96fad776d2)