stride3d/stride · error · InvalidOperationException
Swizzle is out of bound for expression of type
Error message
Swizzle {Accessors[i]} is out of bound for expression {ToString(i)} of type {vectorOrScalarType} What it means
During swizzle coalescing, each character of the first swizzle is converted to an index; if that index is >= the vector's component size, the swizzle reads components that don't exist, so an InvalidOperationException is thrown naming the accessor and expression type.
Solutions
- Fix the swizzle letters so all indices are within the vector size (e.g. v.xy for a float2)
- Verify the declared type of the variable and adjust the swizzle accordingly
- Add a static/validation pass to reject out-of-bounds swizzles before codegen
Example fix
// before float2 v; float f = v.z; // after float2 v; float f = v.y;
Defensive patterns
Strategy: validation
Validate before calling
bool valid = swizzle.All(c => "xyzw".IndexOf(c) < vectorSize) && swizzle.All(c => c is 'x' or 'y' or 'z' or 'w');
Type guard
bool SwizzleInBounds(string swizzle, int size) => swizzle.All(c => "xyzw".IndexOf(c) < size);
Try / catch
try { Compile(expr); } catch (InvalidOperationException e) when (e.Message.Contains("is out of bound")) { ReportSwizzleError(expr, e.Message); } Prevention
- Validate swizzle letters against vector component counts at authoring time
- Enable editor/analyzer checks for SDSL swizzle usage
- Use explicit types in shaders so vector sizes are clear
When it happens
Trigger: A shader expression like float2 v; v.xz where swizzle index (z=2) >= size (2) — i.e. any swizzle accessor beyond the vector's dimension, encountered while merging nested swizzles in Expression.cs.
Common situations: Copy-pasted GLSL code assuming vec4-sized swizzles on a vec2/vec3; dynamic shader generation producing invalid swizzle letters.
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/74aee6fbd197b2d9.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs:917
&& currentValueType is PointerType { BaseType: VectorType or ScalarType } or VectorType or ScalarType
&& Accessors[i] is Identifier { Name: var swizzle1 } id1 && id1.IsVectorSwizzle()
&& Accessors[i + 1] is Identifier { Name: var swizzle2 } id2 && id2.IsVectorSwizzle())
{
var vectorOrScalarType = currentValueType is PointerType p ? p.BaseType : currentValueType;
(var size, ScalarType baseType) = vectorOrScalarType switch
{
ScalarType s => (1, s),
VectorType v => (v.Size, v.BaseType),
_ => throw new NotSupportedException($"Unsupported type {vectorOrScalarType} for swizzle coalescing"),
};
var swizzleIndices = new int[swizzle1.Length];
for (int j = 0; j < swizzle1.Length; ++j)
{
swizzleIndices[j] = ConvertSwizzle(swizzle1[j]);
if (swizzleIndices[j] >= size)
throw new InvalidOperationException($"Swizzle {Accessors[i]} is out of bound for expression {ToString(i)} of type {vectorOrScalarType}");
}
// Combine swizzles with previous ones
var newSwizzleIndices = new int[swizzle2.Length];
for (int j = 0; j < swizzle2.Length; ++j)
{
newSwizzleIndices[j] = swizzleIndices[ConvertSwizzle(swizzle2[j])];
if (newSwizzleIndices[j] >= size)
throw new InvalidOperationException($"Swizzle {Accessors[i + 1]} is out of bound for expression {ToString(i)} of type {currentValueType}");
}
Accessors.RemoveAt(i + 1);
Span<char> vectorFields = ['x', 'y', 'z', 'w'];
Span<char> newSwizzle = stackalloc char[swizzle2.Length];
for (int j = 0; j < swizzle2.Length; ++j)
{
newSwizzle[j] = vectorFields[newSwizzleIndices[j]];
}View on GitHub (pinned to 96fad776d2)