Unity-Technologies/UnityCsReference · error · JSONTypeException

Cannot serialize json value of unknown type

Error message

Cannot serialize json value of unknown type

What it means

When serializing a JSONValue back to a string, the serializer handles string, number, bool, null, list, and dict. The final else branch throws JSONTypeException ("Cannot serialize json value of unknown type") if the wrapped CLR object is none of those. This is essentially unreachable through the library's own New* factories and indicates a JSONValue was constructed directly with an unsupported type.

Source

Thrown at Editor/Mono/AssetStore/Json.cs:309

                string delim = "";
                foreach (KeyValuePair<string, JSONValue> kv in AsDict())
                {
                    res += delim + '"' + EncodeString(kv.Key) + "\" : " + kv.Value;
                    delim = ", ";
                }
                return res + "}";
            }
            else if (IsBool())
            {
                return AsBool() ? "true" : "false";
            }
            else if (IsNull())
            {
                return "null";
            }
            else
            {
                throw new JSONTypeException("Cannot serialize json value of unknown type");
            }
        }

        // Encode a string into a json string
        private static string EncodeString(string str)
        {
            str = str.Replace("\"", "\\\"");
            str = str.Replace("\\", "\\\\");
            str = str.Replace("\b", "\\b");
            str = str.Replace("\f", "\\f");
            str = str.Replace("\n", "\\n");
            str = str.Replace("\r", "\\r");
            str = str.Replace("\t", "\\t");
            // We do not use \uXXXX specifier but direct unicode in the string.
            return str;
        }

        object data;

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Construct JSONValue only through the provided factories (NewString/NewFloat/NewBool/NewList/NewDict/NewNull) or with values known to be string/float/bool.
  2. Convert domain values to primitives before wrapping (e.g. DateTime -> ISO string).
  3. If extending the type set, add a matching branch in the serializer.

Example fix

// before
var node = JSONValue.NewDict();
node["created"] = new JSONValue(System.DateTime.Now); // unsupported type

// after
node["created"] = JSONValue.NewString(System.DateTime.Now.ToString("o"));
Defensive patterns

Strategy: validation

Validate before calling

// Only wrap supported primitives. Convert everything else.
JSONValue Wrap(object o) {
    switch (o) {
        case string s: return JSONValue.NewString(s);
        case float f:  return JSONValue.NewFloat(f);
        case bool b:   return JSONValue.NewBool(b);
        case null:     return JSONValue.NewNull();
        case IEnumerable<JSONValue> l: return JSONValue.NewList(new List<JSONValue>(l));
        default: return JSONValue.NewString(o.ToString());
    }
}

Type guard

static bool IsSerializable(object o) => o is string || o is float || o is bool || o is List<JSONValue> || o is Dictionary<string, JSONValue> || o == null;

Prevention

When it happens

Trigger: Constructing JSONValue with an unsupported CLR type (e.g. new JSONValue(someDateTime), new JSONValue(someObject)); mutating the internal data field to a non-primitive; a subclass introducing a new wrapped type without extending the serializer.

Common situations: Building JSON by hand with domain objects instead of primitives; passing an int or double where the library only stored float (depends on constructor overloads); extending the library incorrectly.

Related errors


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