CoplayDev/unity-mcp · error · ArgumentException

Parameter 'encodedContents' must be valid base64 when…

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.

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.

Appendix: 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)