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
- Fix the swizzle in the shader to stay within the vector's component count
- Change the variable's declared type to a vector large enough for the swizzle
- Check generated/frontend swizzle index computation for off-by-one errors
- 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
- Match swizzle length to the vector size (no .zw on vec2)
- Re-check swizzles after changing vector declarations/fields
- Add semantic analysis tests covering swizzles on vec2/vec3/vec4
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
- Unsupported type for swizzle
- Invalid swizzle for scalar type
- Exception of type 'System.InvalidOperationException' was…
- Unsupported type for swizzle coalescing
- Swizzle is out of bound for expression of type
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)