stride3d/stride · error · InvalidOperationException

Invalid swizzle for vector type

Error message

Invalid swizzle for vector type

What it means

ApplyVectorSwizzles validates each swizzle index against the vector's component count. If any index is >= the vector size (e.g. .zw on a float2), the builder throws InvalidOperationException because SPIR-V OpCompositeExtract/Construct would reference a nonexistent component.

Solutions

  1. Fix the swizzle in the shader to stay within the vector's component count
  2. Change the variable's declared type to a vector large enough for the swizzle
  3. Check generated/frontend swizzle index computation for off-by-one errors
  4. Add shader-side validation or tests for swizzles on small vectors

Example fix

// before (HLSL)
float2 v = ...;
float4 w = v.xyzw;
// after
float4 v4 = float4(v, 0.0, 0.0);
float4 w = v4.xyzw;
Defensive patterns

Strategy: validation

Validate before calling

// Validate swizzle indices against vector size before applying
if (targetType is VectorType v && swizzle.Indices.Any(i => i >= v.Size))
    throw new ShaderSemanticException($"Swizzle component out of range for {v.Size}-component vector");

Type guard

bool IsValidVectorSwizzle(VectorType v, ReadOnlySpan<int> idx) { foreach (var i in idx) if (i < 0 || i >= v.Size) return false; return idx.Length > 0; }

Try / catch

try { var r = ApplySwizzles(context, vecValue, swizzle); }
catch (InvalidOperationException ex) when (ex.Message == "Invalid swizzle for vector type") { throw new ShaderSemanticException("Swizzle exceeds vector component count", ex); }

Prevention

When it happens

Trigger: Swizzling a vector with component letters beyond its length, e.g. float2 v; v.z or v.xyz on a vec2; swizzleIndices[j] >= v.Size.

Common situations: Typos in shader code (using .xyz on vec2); refactoring that changed a vec4 to vec2 without updating swizzles; code generator emitting wrong swizzle letters.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

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

        {
            if (swizzleIndices[j] != 0)
                throw new InvalidOperationException("Invalid swizzle for scalar type");

            constructIndices[j] = value.Id;
        }

        SpirvValue result;
        var construct = InsertData(new OpCompositeConstruct(context.GetOrRegister(resultType), context.Bound++, new(constructIndices)));
        result = new(construct);
        return (result, resultType);
    }

    public (SpirvValue, SymbolType) ApplyVectorSwizzles(SpirvContext context, SpirvValue value, VectorType v, Span<int> swizzleIndices)
    {
        for (int j = 0; j < swizzleIndices.Length; ++j)
        {
            if (swizzleIndices[j] >= v.Size)
                throw new InvalidOperationException("Invalid swizzle for vector type");
        }

        if (swizzleIndices.Length > 1)
        {
            // Apply swizzle
            var resultType = new VectorType(v.BaseType, swizzleIndices.Length);
            var shuffle = InsertData(new OpVectorShuffle(context.GetOrRegister(resultType), context.Bound++, value.Id, value.Id, new(swizzleIndices)));
            value = new(shuffle);

            return (value, resultType);
        }
        else if (swizzleIndices.Length == 1)
        {
            // Apply swizzle
            var resultType = v.BaseType;
            var extract = InsertData(new OpCompositeExtract(context.GetOrRegister(resultType), context.Bound++, value.Id, [swizzleIndices[0]]));
            value = new(extract);

View on GitHub (pinned to 96fad776d2)