{"record":{"id":"0023f0477ba8a5c0","repo":"stride3d/stride","slug":"color-attribute-can-only-be-applied-on-float3-float4-vector","errorCode":null,"errorMessage":"[Color] attribute can only be applied on float3/float4 vector types","messagePattern":"\\[Color\\] attribute can only be applied on float3/float4 vector types","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs","lineNumber":474,"sourceCode":"                    var metadata = cbufferMetadata[index];\n\n                    memberInfos[index] = new EffectValueDescription\n                    {\n                        Type = ConvertType(context, member.Type, member.TypeModifier, SpirvBuilder.AlignmentRules.CBuffer),\n                        RawName = member.Name,\n                        KeyInfo = new EffectParameterKeyInfo { KeyName = metadata.Link },\n                        Offset = constantBufferOffset,\n                        Size = memberSize,\n                        LogicalGroup = metadata.LogicalGroup,\n                        DefaultValue = ConvertDefaultValue(metadata.DefaultValue),\n                    };\n                    if (metadata.Color)\n                    {\n                        var baseType = member.Type;\n                        while (baseType is ArrayType arrayType)\n                            baseType = arrayType.BaseType;\n                        if (baseType is not VectorType { BaseType: { Type: Scalar.Float }, Size: 3 or 4 })\n                            throw new InvalidOperationException(\"[Color] attribute can only be applied on float3/float4 vector types\");\n                        memberInfos[index].Type.Class = EffectParameterClass.Color;\n                    }\n\n                    // Adjust offset for next item\n                    constantBufferOffset += memberSize;\n                    SpirvBuilder.PadOffsetAfterArray(member.Type, member.TypeModifier, memberInfos[index].Offset, ref constantBufferOffset, SpirvBuilder.AlignmentRules.CBuffer);\n                }\n\n                var cbufferDesc = new EffectConstantBufferDescription\n                {\n                    Name = context.Names[cbuffer.VariableId],\n                    // Round buffer size to next multiple of 16 bytes\n                    Size = (constantBufferOffset + 15) / 16 * 16,\n\n                    Type = ConstantBufferType.ConstantBuffer,\n                    Members = memberInfos,\n                };\n                globalContext.Reflection.ConstantBuffers.Add(cbufferDesc);","sourceCodeStart":456,"sourceCodeEnd":492,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs#L456-L492","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n[Color] float2 Tint;\n// after\n[Color] float4 Tint;","handlingStrategy":"validation","validationCode":"// SDSL source check before compiling\nif (attrName == \"Color\" && !(type is \"float3\" or \"float4\"))\n    throw new ArgumentException(\"[Color] requires float3/float4\");","typeGuard":"bool IsValidColorAttr(TypeDescription t) =>\n    t is VectorType { BaseType: { Type: Scalar.Float }, Size: 3 or 4 };","tryCatchPattern":"try { result = mixer.MergeSDSL(tree); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"[Color] attribute\")) {\n    reportShaderSourceError(shaderUrl, ex.Message);\n}","preventionTips":["Only annotate float3/float4 uniforms with [Color]","Review cbuffer members after porting from other shader languages","Add shader-source lint for attribute/type pairs"],"tags":["shaders","sdsl","attributes","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}