stride3d/stride · error · NotSupportedException

Unsupported element type

Error message

Unsupported element type {valueType} in composite extraction

What it means

While extracting the j-th element of a composite value during literal compilation, the element's type must be a MatrixType, VectorType, or ScalarType to be lowered via OpCompositeExtract/convert. Other element types are rejected, so nested composites of unexpected kinds cannot be flattened.

Solutions

  1. Flatten nested aggregate literals manually into scalar expressions
  2. Restrict literal element types to scalars (or vectors/matrices where supported)
  3. Check that the literal's declared element type matches the actual sub-expression types

Example fix

// before
float2x2 m = { float2[]{1,2}, float2[]{3,4} }; // nested array element
// after
float2x2 m = { 1, 2, 3, 4 }; // scalar elements
Defensive patterns

Strategy: type-guard

Validate before calling

// Ensure every element expression compiles to a scalar/vector/matrix value
bool AllSupportedElements(IEnumerable<TypeBase> elemTypes) =>
    elemTypes.All(t => t is ScalarType or VectorType or MatrixType);

Type guard

bool IsExtractable(TypeBase t) => t is ScalarType or VectorType or MatrixType;

Try / catch

try { literal.Compile(context, builder); }
catch (NotSupportedException ex) when (ex.Message.Contains("Unsupported element type")) { /* flatten the initializer manually */ }

Prevention

When it happens

Trigger: A composite literal contains elements whose resolved Spirv type is neither scalar, vector, nor matrix — e.g. arrays of arrays or struct-typed elements inside a vector/matrix/array literal.

Common situations: Nested aggregate initializers beyond the supported one-level flatten; array literals whose element type itself is an unsupported composite.

Related errors


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs:212

        for (int i = 0; i < Values.Count; i++)
        {
            // Note: we can compute expected element type only if there are as many source values as expected elements
            // i.e. float3(float, float, float) is OK but float3(float, float2) is not as we don't know which element will be which before compiling them (we would need 2-pass compilation for that)
            var value = Values[i].CompileAsValue(table, compiler, expectedElementType);
            var valueType = Values[i].ValueType;

            // We expand elements, because float4 can be created from (float, float2, float), or (float2x2)
            if (Type is ScalarType or VectorType or MatrixType)
            {
                var sourceElementType = valueType!.GetElementType();
                for (int j = 0; j < valueType!.GetElementCount(); ++j)
                {
                    SpirvValue extractedValue = valueType switch
                    {
                        MatrixType m => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(sourceElementType), context.Bound++, value.Id, [j / m.Columns, j % m.Rows]))),
                        VectorType v => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(sourceElementType), context.Bound++, value.Id, [j]))),
                        ScalarType s => value,
                        _ => throw new NotSupportedException($"Unsupported element type {valueType} in composite extraction"),
                    };
                    // If too many elments, keep counting so that exception is still thrown a bit later, with total count
                    var currentElementIndex = elementIndex++;
                    if (currentElementIndex >= values.Length)
                        continue;
                    values[currentElementIndex] = builder.Convert(context, extractedValue, expectedElementType).Id;
                }
            }
            else if (Type is ArrayType arrayType)
            {
                values[elementIndex++] = builder.Convert(context, value, expectedElementType).Id;
            }
        }

        // Scalar splat: float3(x) means float3(x, x, x)
        if (elementIndex == 1 && totalCount > 1 && Type is VectorType or MatrixType)
        {
            for (int j = 1; j < totalCount; ++j)

View on GitHub (pinned to 96fad776d2)