CoplayDev/unity-mcp · error · ArgumentException

Color array must have 3 or 4 elements.

Error message

Color array must have 3 or 4 elements.

What it means

When parsing a Color from a JSON token, MaterialOps accepts a 4-element array [r,g,b,a] or a 3-element array [r,g,b] (alpha defaults to 1f). Any other length falls through to the final 'else' and throws ArgumentException. This enforces a strict color-array contract before delegating to the Newtonsoft serializer.

Source

Thrown at MCPForUnity/Editor/Helpers/MaterialOps.cs:382

                    return new Color(
                        (float)jArray[0],
                        (float)jArray[1],
                        (float)jArray[2],
                        (float)jArray[3]
                    );
                }
                else if (jArray.Count == 3)
                {
                    return new Color(
                        (float)jArray[0],
                        (float)jArray[1],
                        (float)jArray[2],
                        1f
                    );
                }
                else
                {
                    throw new ArgumentException("Color array must have 3 or 4 elements.");
                }
            }

            try
            {
                return token.ToObject<Color>(serializer);
            }
            catch (Exception ex)
            {
                McpLog.Warn($"[MaterialOps] Failed to parse color from token: {ex.Message}");
                throw;
            }
        }
    }
}

View on GitHub (pinned to c21bf496bc)

Solutions

  1. Send exactly 3 ([r,g,b]) or 4 ([r,g,b,a]) float values, each typically in 0..1.
  2. Validate the array length client-side before calling the material color API.
  3. If the API accepts a hex string or named color object, prefer that over a raw array.

Example fix

// before
{"color": [1, 0, 0, 1, 0]}

// after
{"color": [1, 0, 0, 1]}  // RGBA
Defensive patterns

Strategy: validation

Validate before calling

// Validate the color array shape before sending to the material API.
bool IsValidColorArray(JArray arr) => arr != null && (arr.Count == 3 || arr.Count == 4)
    && arr.All(t => t.Type == JTokenType.Float || t.Type == JTokenType.Integer);

if (!IsValidColorArray(colorArr))
    throw new ArgumentException("color must be [r,g,b] or [r,g,b,a] floats.");

Type guard

static bool IsColorArray(JToken t)
{
    if (t == null || t.Type != JTokenType.Array) return false;
    var a = (JArray)t;
    return (a.Count == 3 || a.Count == 4)
        && a.All(x => x.Type == JTokenType.Float || x.Type == JTokenType.Integer);
}

Try / catch

try { material.SetColor(prop, ParseColor(token)); }
catch (ArgumentException ex) when (ex.Message.Contains("Color array"))
{
    // Fall back to a default or ask the caller for a corrected color array.
    material.SetColor(prop, Color.white);
}

Prevention

When it happens

Trigger: Passing a JSON color array with 0, 1, 2, or 5+ numeric elements (e.g. [1,2] or [1,2,3,4,5]); passing nested arrays or a single number where an array is expected. The 4-case is handled above the shown source; the 3-case is shown; everything else hits the else.

Common situations: An AI/LLM generating material color parameters with the wrong arity; hand-built JSON with a typo or extra component; passing an HDR/linear color with an intensity suffix; confusing a hex string with an array.

Related errors


AI-assisted analysis of CoplayDev/unity-mcp@c21bf496bc (2026-08-13). Data as JSON: /api/errors/2cfd887ad91fdfcd. Report an issue: GitHub.