stride3d/stride · error · InvalidOperationException
[Color] attribute can only be applied on float3/float4…
Error message
[Color] attribute can only be applied on float3/float4 vector types
What it means
The SDSL [Color] attribute marks a cbuffer member as an editor color picker, which only makes sense for float3/float4 vectors. ComputeCBufferReflection validates the member's (array-unwrapped) base type and throws if it is not a 3- or 4-component float vector.
Solutions
- Change the member type to float3 or float4
- Remove the [Color] attribute if the type must stay non-vector
- If a 2-component color is needed, pad to float4 and remove the attribute or use a float4
Example fix
// before [Color] float2 Tint; // after [Color] float4 Tint;
Defensive patterns
Strategy: validation
Validate before calling
// SDSL source check before compiling
if (attrName == "Color" && !(type is "float3" or "float4"))
throw new ArgumentException("[Color] requires float3/float4"); Type guard
bool IsValidColorAttr(TypeDescription t) =>
t is VectorType { BaseType: { Type: Scalar.Float }, Size: 3 or 4 }; Try / catch
try { result = mixer.MergeSDSL(tree); }
catch (InvalidOperationException ex) when (ex.Message.Contains("[Color] attribute")) {
reportShaderSourceError(shaderUrl, ex.Message);
} Prevention
- Only annotate float3/float4 uniforms with [Color]
- Review cbuffer members after porting from other shader languages
- Add shader-source lint for attribute/type pairs
When it happens
Trigger: Annotating a cbuffer member with [Color] when its type is float2, float, int3, or any non-vector type; [Color] on an array whose element type is not float3/float4; a renamed/aliased type resolving to Scalar other than Float.
Common situations: Copying [Color] onto an int-based HDR or hex-color uniform; typos like `float2 Color [Color]`; shaders ported from engines where [Color] accepts other widths.
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
- Could not find cbuffer member link info for
- Unsupported float vector size
- Unsupported int vector size
- Unsupported uint vector size
- Unsupported constant composite element type
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/0023f0477ba8a5c0.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs:474
var metadata = cbufferMetadata[index];
memberInfos[index] = new EffectValueDescription
{
Type = ConvertType(context, member.Type, member.TypeModifier, SpirvBuilder.AlignmentRules.CBuffer),
RawName = member.Name,
KeyInfo = new EffectParameterKeyInfo { KeyName = metadata.Link },
Offset = constantBufferOffset,
Size = memberSize,
LogicalGroup = metadata.LogicalGroup,
DefaultValue = ConvertDefaultValue(metadata.DefaultValue),
};
if (metadata.Color)
{
var baseType = member.Type;
while (baseType is ArrayType arrayType)
baseType = arrayType.BaseType;
if (baseType is not VectorType { BaseType: { Type: Scalar.Float }, Size: 3 or 4 })
throw new InvalidOperationException("[Color] attribute can only be applied on float3/float4 vector types");
memberInfos[index].Type.Class = EffectParameterClass.Color;
}
// Adjust offset for next item
constantBufferOffset += memberSize;
SpirvBuilder.PadOffsetAfterArray(member.Type, member.TypeModifier, memberInfos[index].Offset, ref constantBufferOffset, SpirvBuilder.AlignmentRules.CBuffer);
}
var cbufferDesc = new EffectConstantBufferDescription
{
Name = context.Names[cbuffer.VariableId],
// Round buffer size to next multiple of 16 bytes
Size = (constantBufferOffset + 15) / 16 * 16,
Type = ConstantBufferType.ConstantBuffer,
Members = memberInfos,
};
globalContext.Reflection.ConstantBuffers.Add(cbufferDesc);View on GitHub (pinned to 96fad776d2)