stride3d/stride · error · InvalidOperationException
Invalid swizzle for scalar type
Error message
Invalid swizzle for scalar type
What it means
ApplyScalarSwizzles builds a vector by repeating a scalar value for each swizzle index. HLSL semantics allow repeating a scalar (any swizzle like .xxx works), but this implementation requires every index to be exactly 0; if any swizzle index is non-zero on a scalar it throws InvalidOperationException.
Solutions
- Fix the shader so the value is a vector before swizzling (construct a vector explicitly)
- Use only the x component when replicating a scalar: s.xxxx instead of s.yyyy
- Verify the symbol's inferred type is a vector, not a scalar
- Update builder to treat scalar broadcast as always valid per HLSL rules
Example fix
// before (HLSL) float s = 1.0; float2 v = s.yx; // after float s = 1.0; float2 v = float2(s, s); // or s.xx
Defensive patterns
Strategy: type-guard
Validate before calling
// Scalars can only be replicated via index 0 (x)
if (targetType is ScalarType && swizzle.Indices.Any(i => i != 0))
throw new ShaderSemanticException("Scalar swizzle components must be 'x'"); Type guard
bool IsValidScalarSwizzle(ReadOnlySpan<int> idx) { foreach (var i in idx) if (i != 0) return false; return idx.Length > 0; } Try / catch
try { var r = ApplySwizzles(context, scalarValue, swizzle); }
catch (InvalidOperationException ex) when (ex.Message == "Invalid swizzle for scalar type") { throw new ShaderSemanticException("Cannot swizzle scalar with non-x components", ex); } Prevention
- Use s.xxxx (or construct a vector) to replicate scalars, never s.yyy
- Fix the value's declared type to a vector if component letters are intended
- Lint shader code for swizzles on scalar-valued symbols
When it happens
Trigger: Swizzling a scalar value with an index other than 0 (e.g. s.y or s.zw) reaching ApplySwizzles -> ApplyScalarSwizzles; swizzleIndices[j] != 0 for some j.
Common situations: Shader code that treats a float as if it were a vector, e.g. float f = 1.0; float2 v = f.yz; or frontend mislabeling a vector as scalar.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Unsupported type for swizzle
- Invalid swizzle for vector 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/1df88b2b59dee129.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs:46
{
var valueType = context.ReverseTypes[value.TypeId];
return valueType switch
{
ScalarType s => ApplyScalarSwizzles(context, value, s, swizzleIndices),
VectorType v => ApplyVectorSwizzles(context, value, v, swizzleIndices),
_ => throw new NotSupportedException($"Unsupported type for swizzle: {valueType}"),
};
}
public (SpirvValue, SymbolType) ApplyScalarSwizzles(SpirvContext context, SpirvValue value, ScalarType s, Span<int> swizzleIndices)
{
var resultType = new VectorType(s, swizzleIndices.Length);
Span<int> constructIndices = stackalloc int[swizzleIndices.Length];
for (int j = 0; j < constructIndices.Length; ++j)
{
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");
}
View on GitHub (pinned to 96fad776d2)