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
- Construct JSONValue only through the provided factories (NewString/NewFloat/NewBool/NewList/NewDict/NewNull) or with values known to be string/float/bool.
- Convert domain values to primitives before wrapping (e.g. DateTime -> ISO string).
- 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
- Always build JSONValue via the New* factories, never new JSONValue(arbitraryObject).
- Convert domain types (DateTime, enums, structs) to primitives before wrapping.
- Add a unit test that round-trips (build -> serialize) every value you construct.
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
- Tried to read non-string json value as string
- Tried to read non-float json value as float
- Tried to read non-bool json value as bool
- Tried to read {} json value as list
- Tried to read non-dictionary json value as dictionary
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/3d992de24b3e64fe.
Report an issue: GitHub.