Unity-Technologies/UnityCsReference · error · FormatException

Expected {o} to be a string or a Type. It is a {o.GetType()}

Error message

Expected {o} to be a string or a Type. It is a {o.GetType()}

What it means

Thrown by the private TypeOrTypeName helper when its input is neither a Type nor a string. The helper coerces an object into a Type for the macro evaluator's known-type resolution; any other runtime type falls through to a FormatException.

Source

Thrown at Editor/Mono/Macros/MethodEvaluator.cs:137

                null, paramTypes, null);
            if (method == null)
                throw new ArgumentException(string.Format(
                    "Method {0}.{1}({2}) not found in assembly {3}!", typeName,
                    methodName, ToCommaSeparatedString(paramTypes),
                    assembly.FullName));
            return method.Invoke(null, args);
        }

        private static Type TypeOrTypeName(object o)
        {
            switch (o)
            {
                case Type t:
                    return t;
                case string s:
                    return Type.GetType(s);
                default:
                    throw new FormatException($"Expected {o} to be a string or a Type. It is a {o.GetType()}");
            }
        }

        private static Type[] TypesOrTypeNames(object o)
        {

            switch (o)
            {
                case Type[] t:
                    return t;
                case string[] s:
                    return Array.ConvertAll(s, Type.GetType);
                default:
                    throw new FormatException($"Expected {o} to be a string[] or a Type[]. It is a {o.GetType()}");
            }
        }

        public static object ExecuteExternalCode(string parcel)

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Regenerate the eval data parcel with the current evaluator so known-type entries are Type or string.
  2. Ensure the parcel is produced and consumed by the same Unity/editor version to avoid deserialization drift.
  3. Validate each known-type entry is a Type or string before invoking ExecuteExternalCode.
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(o is Type) && !(o is string)) throw new FormatException($"Expected Type or string, got {o?.GetType()}");

Type guard

static bool IsTypeOrTypeName(object o) => o is Type || o is string;

Try / catch

try { /* evaluator call */ }
catch (FormatException ex) when (ex.Message.Contains("string or a Type")) { Debug.LogError($"Bad known-type entry: {ex.Message}"); }

Prevention

When it happens

Trigger: An EvalDataParcel known-types payload contains an element that deserializes to a type other than Type or string (e.g. an int, an enum, or a custom serialized object). Corrupted or version-mismatched eval parcel data.

Common situations: External code execution (ExecuteExternalCode) invoked with a base64 parcel whose known-type entries were serialized by an incompatible Unity/tooling version, producing unexpected element types after deserialization.

Related errors


AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13). Data as JSON: /api/errors/9f1e82a2535f41be. Report an issue: GitHub.