CoplayDev/unity-mcp · error · JsonSerializationException
Cannot deserialize Quaternion from {token.Type}: '{token}'
Error message
Cannot deserialize Quaternion from {token.Type}: '{token}' What it means
Thrown by QuaternionConverter.ReadJson when the JSON token is neither a JArray with count >= 4 nor a JObject. Quaternion accepts [x, y, z, w] array form or {"x":..,"y":..,"z":..,"w":..} object form. Any other JSON structure is rejected.
Source
Thrown at MCPForUnity/Runtime/Serialization/UnityTypeConverters.cs:89
writer.WriteStartObject();
writer.WritePropertyName("x");
writer.WriteValue(value.x);
writer.WritePropertyName("y");
writer.WriteValue(value.y);
writer.WritePropertyName("z");
writer.WriteValue(value.z);
writer.WritePropertyName("w");
writer.WriteValue(value.w);
writer.WriteEndObject();
}
public override Quaternion ReadJson(JsonReader reader, Type objectType, Quaternion existingValue, bool hasExistingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
if (token is JArray arr && arr.Count >= 4)
return new Quaternion((float)arr[0], (float)arr[1], (float)arr[2], (float)arr[3]);
if (token is not JObject jo)
throw new JsonSerializationException($"Cannot deserialize Quaternion from {token.Type}: '{token}'");
return new Quaternion(
(float)jo["x"],
(float)jo["y"],
(float)jo["z"],
(float)jo["w"]
);
}
}
public class ColorConverter : JsonConverter<Color>
{
public override void WriteJson(JsonWriter writer, Color value, JsonSerializer serializer)
{
writer.WriteStartObject();
writer.WritePropertyName("r");
writer.WriteValue(value.r);
writer.WritePropertyName("g");
writer.WriteValue(value.g);View on GitHub (pinned to c21bf496bc)
Solutions
- Send rotation as a 4-element quaternion array [x, y, z, w]: "rotation": [0, 0, 0, 1].
- Or send as object: "rotation": {"x": 0, "y": 0, "z": 0, "w": 1}.
- If you have Euler angles, convert to quaternion before sending (or check if the tool accepts a separate eulerRotation parameter).
- Ensure the array has exactly 4 elements (identity quaternion is [0,0,0,1]).
Example fix
// before (Euler angles sent as 3-element array)
params = {"rotation": [0, 90, 0]}
// after (proper quaternion)
params = {"rotation": [0, 0.7071, 0, 0.7071]} Defensive patterns
Strategy: type-guard
Validate before calling
import math
def is_valid_quaternion(val) -> bool:
if isinstance(val, (list, tuple)) and len(val) >= 4:
return all(isinstance(v, (int, float)) for v in val[:4])
if isinstance(val, dict):
return all(k in val for k in ('x', 'y', 'z', 'w'))
return False
def euler_to_quaternion(rx, ry, rz):
"""Convert Euler degrees to quaternion [x,y,z,w]."""
rx, ry, rz = map(math.radians, [rx, ry, rz])
cx, cy, cz = math.cos(rx/2), math.cos(ry/2), math.cos(rz/2)
sx, sy, sz = math.sin(rx/2), math.sin(ry/2), math.sin(rz/2)
return [cx*cy*cz + sx*sy*sz, sx*cy*cz - cx*sy*sz,
cx*sy*cz + sx*cy*sz, cx*cy*sz - sx*sy*cz] Type guard
function isQuaternion(val: unknown): val is number[] | {x:number;y:number;z:number;w:number} {
if (Array.isArray(val) && val.length >= 4)
return val.slice(0, 4).every(v => typeof v === 'number');
if (val && typeof val === 'object' && 'x' in val && 'y' in val && 'z' in val && 'w' in val)
return true;
return false;
} Try / catch
try
{
var quat = serializer.Deserialize<Quaternion>(reader);
}
catch (JsonSerializationException ex) when (ex.Message.Contains("Cannot deserialize Quaternion"))
{
return new ErrorResponse($"Quaternion must be [x,y,z,w] or {{x,y,z,w}}. Identity = [0,0,0,1].");
} Prevention
- Remember quaternions have 4 components [x,y,z,w], not 3 (Euler).
- Identity rotation is [0, 0, 0, 1].
- Convert Euler angles to quaternions before sending, or check for a separate euler parameter.
- Don't send a 3-element array for rotation fields.
When it happens
Trigger: Deserializing a rotation field from JSON where the value is a scalar, string, object missing the 'w' component, or an array with fewer than 4 elements. Also triggered when Euler angles are sent where a quaternion is expected.
Common situations: Client sends Euler angles (3-element array) where a quaternion (4-element) is expected; AI outputs rotation as "90" (scalar); object missing the 'w' field; confusion between Euler (Vector3) and quaternion (Vector4) representations.
Related errors
- Cannot deserialize Vector3 from {token.Type}: '{token}'
- Cannot deserialize Vector2 from {token.Type}: '{token}'
- Cannot deserialize Vector4 from {token.Type}: '{token}'
- Expected JSON object or null when deserializing Matrix4x4, g
- OpenClaw config contains non-JSON content and cannot be safe
AI-assisted analysis of CoplayDev/unity-mcp@c21bf496bc (2026-08-13).
Data as JSON: /api/errors/891e5e1dc82170e1.
Report an issue: GitHub.