stride3d/stride · error · InvalidOperationException
Swizzle is out of bound for expression of type
Error message
Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType} What it means
During compilation of a swizzle applied to a vector value, each swizzle character is converted to an index and checked against the vector's Size. If any swizzle index is >= the vector size (e.g. .zw on a float2), the compiler throws this error because the swizzle reads components that don't exist on the value's type.
Solutions
- Reduce the swizzle to components that exist for the operand's vector size (float2 has x/y only, float3 x/y/z).
- Change the variable's declared type to a larger vector if more components are genuinely needed.
- Refactor swizzles that were copied from differently-sized vectors.
Example fix
// before float2 uv = ...; float x = uv.z; // z out of bounds for float2 // after float x = uv.y; // or declare uv as float4 to use .z/.w
Defensive patterns
Strategy: validation
Validate before calling
// validate swizzle length against vector size before applying
if (swizzle.Length > v.Size || swizzle.Any(c => ConvertSwizzle(c) >= v.Size))
throw new InvalidOperationException("Swizzle exceeds vector component count"); Type guard
static bool IsSwizzleInBounds(string swizzle, int vectorSize) => swizzle.All(c => "xyzw".IndexOf(c) < vectorSize);
Try / catch
try { CompileShader(source); }
catch (InvalidOperationException e) when (e.Message.StartsWith("Swizzle") && e.Message.Contains("out of bound"))
{
// fix the swizzle or widen the vector type
} Prevention
- Keep swizzle components within the operand's vector size (float2: x/y, float3: x/y/z).
- Re-check swizzles after changing a variable's vector width.
- Avoid copy-pasting swizzles between differently sized vectors.
When it happens
Trigger: Applying a vector swizzle (compiler != null path) where a converted swizzle index is greater than or equal to v.Size of the operand vector type — e.g. float2.xxx is fine but float2.z is not.
Common situations: Swizzling a float2/float3 with out-of-range components (.z on float2, .w on float3), copy-pasting swizzles between variables of different vector sizes, or generic/template shader code that assumes a larger vector.
Related errors
- Swizzle is out of bound for expression of type
- Swizzle is out of bound for expression of type
- Unsupported type for swizzle coalescing
- Invalid swizzle character
- Struct not found in shader
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/55f65867c2cbeb55.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs:1240
if (swizzle.Length > 1)
{
if (compiler == null)
{
accessor.Type = new VectorType(v.BaseType, swizzle.Length);
break;
}
// Load value
var (builder, context) = compiler;
EmitOpAccessChain(accessChainIds, i - 1);
result = new(builder.InsertData(new OpLoad(context.GetOrRegister(v), context.Bound++, result.Id, null, [])));
var swizzleIndices = swizzleBuffer[..swizzle.Length];
for (int j = 0; j < swizzle.Length; ++j)
{
swizzleIndices[j] = ConvertSwizzle(swizzle[j]);
if (swizzleIndices[j] >= v.Size)
throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}");
}
(result, _) = builder.ApplyVectorSwizzles(context, result, v, swizzleIndices);
}
else
{
// Keep as a pointer
if (compiler == null)
{
accessor.Type = new PointerType(v.BaseType, p.StorageClass);
break;
}
var (builder, context) = compiler;
PushAccessChainId(accessChainIds, context.CompileConstant(ConvertSwizzle(swizzle[0])).Id);
}
break;
case (VectorType v, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle():View on GitHub (pinned to 96fad776d2)