stride3d/stride · error · InvalidOperationException
Swizzle is out of bound for expression of type
Error message
Swizzle {Accessors[i + 1]} is out of bound for expression {ToString(i)} of type {currentValueType} What it means
In the second phase of swizzle coalescing, indices produced by combining swizzle1 and swizzle2 are validated against the vector size; if a combined index exceeds the component count, an InvalidOperationException is thrown naming the outer accessor (Accessors[i+1]) and the expression's type.
Solutions
- Ensure the outer swizzle letters fit the inner swizzle's component count (e.g. v.xy.yx, not v.xy.z)
- Reduce chained swizzles into a single swizzle in the shader source
- Validate swizzle letters against component counts before compiling
Example fix
// before float2 v; float f = v.xy.z; // after float2 v; float f = v.xy.x;
Defensive patterns
Strategy: validation
Validate before calling
bool outerValid = outerSwizzle.All(c => "xyzw".IndexOf(c) < innerSwizzle.Length);
Type guard
bool ChainedSwizzleValid(string inner, string outer) => outer.All(c => "xyzw".IndexOf(c) < inner.Length);
Try / catch
try { Compile(expr); } catch (InvalidOperationException e) when (e.Message.Contains("is out of bound")) { ReportSwizzleError(expr, e.Message); } Prevention
- Ensure chained swizzle letters never exceed the inner swizzle's length
- Collapse nested swizzles manually in source before compilation
- Add unit tests covering chained-swizzle combinations
When it happens
Trigger: Chained swizzles where the OUTER swizzle selects beyond the result size of the inner swizzle, e.g. float2 v; v.xy.z — inner yields 2 components but outer index z=2 is out of range.
Common situations: Nested/double swizzles ported from other languages; generated shader code composing swizzles programmatically with mismatched lengths.
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/6c9351ea2e87b6c3.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs:926
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]];
}
Accessors[i] = accessor = new Identifier(new(newSwizzle), default);
}
}
// Some accessors push up to 2 values on the stack
Span<int> accessChainIds = stackalloc int[Accessors.Count * 2];
Span<int> swizzleBuffer = stackalloc int[4]; // max swizzle length
View on GitHub (pinned to 96fad776d2)