CoplayDev/unity-mcp · error · ArgumentException

Parameter 'encodedContents' must be valid base64 when 'conte

Error message

Parameter 'encodedContents' must be valid base64 when 'contentsEncoded' is true.

What it means

Thrown by GetDecodedContents when 'contentsEncoded' (or 'contents_encoded') is true and the supplied 'encodedContents' string is not valid Base64. Convert.FromBase64String raises a FormatException that is wrapped in this ArgumentException. The method expects UTF-8 text that was Base64-encoded client-side before transport.

Source

Thrown at MCPForUnity/Editor/Tools/ManageUI.cs:1808

            return $"#{ColorUtility.ToHtmlStringRGBA(c)}";
        }

        private static string GetDecodedContents(ToolParams p)
        {
            bool isEncoded = p.GetBool("contents_encoded") || p.GetBool("contentsEncoded");

            if (isEncoded)
            {
                string encoded = p.Get("encoded_contents") ?? p.Get("encodedContents");
                if (!string.IsNullOrEmpty(encoded))
                {
                    try
                    {
                        return Encoding.UTF8.GetString(Convert.FromBase64String(encoded));
                    }
                    catch (FormatException ex)
                    {
                        throw new ArgumentException(
                            "Parameter 'encodedContents' must be valid base64 when 'contentsEncoded' is true.",
                            ex);
                    }
                }
            }

            return p.Get("contents");
        }

        /// <summary>
        /// Validates UXML content before writing to disk.
        /// Returns null if valid, or an error message if malformed.
        /// Populates warnings list with non-fatal issues.
        /// Uses XmlParserContext to pre-declare common UXML namespace prefixes
        /// (ui, uie, engine, editor) since Unity's parser is more lenient than System.Xml.
        /// </summary>

        /// <summary>

View on GitHub (pinned to c21bf496bc)

Solutions

  1. Base64-encode the raw UTF-8 string before sending it (e.g. Python: base64.b64encode(content.encode('utf-8')).decode('ascii')).
  2. If the content is plain text, set contentsEncoded=false (or omit it) and pass the raw string in 'contents' instead.
  3. Verify the encoded value round-trips: decode it locally and confirm the output matches the original before sending.
  4. Strip any data-URI prefix or whitespace/newlines from the encoded string before passing it.

Example fix

// before
params = {"contentsEncoded": true, "encodedContents": "<UXML>...</UXML>"}
// after
import base64
params = {"contentsEncoded": true, "encodedContents": base64.b64encode(uxml.encode('utf-8')).decode('ascii')}
Defensive patterns

Strategy: validation

Validate before calling

import base64

def validate_encoded_contents(encoded: str) -> bool:
    """Returns True if the string is valid Base64."""
    try:
        base64.b64decode(encoded, validate=True)
        return True
    except Exception:
        return False

# before sending:
if not validate_encoded_contents(params['encodedContents']):
    raise ValueError('encodedContents is not valid base64')

Try / catch

// C# caller wrapping the tool invocation
try
{
    var decoded = GetDecodedContents(p);
}
catch (ArgumentException ex) when (ex.Message.Contains("must be valid base64"))
{
    // Log and fall back to plain 'contents' or re-prompt the caller
    logger.Warn($"Base64 decode failed; falling back to raw contents.");
    return p.Get("contents");
}

Prevention

When it happens

Trigger: Calling a ManageUI tool (e.g. create_uxml, write_visual_element) with contentsEncoded=true but providing a plain-text, partially-encoded, or whitespace-padded string in encodedContents/encoded_contents. Also triggered by passing a data-URI prefix like 'data:text/plain;base64,...' without stripping the header.

Common situations: AI assistant sends raw UXML instead of Base64; encoding library adds newlines every 76 chars that confuse the decoder; copy-paste truncates the Base64 string; client uses URL-safe Base64 (- and _) instead of standard (+ and /).

Related errors


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