{"record":{"id":"adfa8e92f76c418a","repo":"CoplayDev/unity-mcp","slug":"expected-json-object-or-null-when-deserializing-ma","errorCode":null,"errorMessage":"Expected JSON object or null when deserializing Matrix4x4, got '{reader.TokenType}'.","messagePattern":"Expected JSON object or null when deserializing Matrix4x4, got '(.+?)'\\.","errorType":"exception","errorClass":"JsonSerializationException","httpStatus":null,"severity":"error","filePath":"MCPForUnity/Runtime/Serialization/UnityTypeConverters.cs","lineNumber":245,"sourceCode":"            writer.WritePropertyName(\"m13\"); writer.WriteValue(value.m13);\n            writer.WritePropertyName(\"m20\"); writer.WriteValue(value.m20);\n            writer.WritePropertyName(\"m21\"); writer.WriteValue(value.m21);\n            writer.WritePropertyName(\"m22\"); writer.WriteValue(value.m22);\n            writer.WritePropertyName(\"m23\"); writer.WriteValue(value.m23);\n            writer.WritePropertyName(\"m30\"); writer.WriteValue(value.m30);\n            writer.WritePropertyName(\"m31\"); writer.WriteValue(value.m31);\n            writer.WritePropertyName(\"m32\"); writer.WriteValue(value.m32);\n            writer.WritePropertyName(\"m33\"); writer.WriteValue(value.m33);\n            writer.WriteEndObject();\n        }\n\n        public override Matrix4x4 ReadJson(JsonReader reader, Type objectType, Matrix4x4 existingValue, bool hasExistingValue, JsonSerializer serializer)\n        {\n            if (reader.TokenType == JsonToken.Null)\n                return new Matrix4x4(); // Return zero matrix for null (consistent with missing field defaults)\n\n            if (reader.TokenType != JsonToken.StartObject)\n                throw new JsonSerializationException($\"Expected JSON object or null when deserializing Matrix4x4, got '{reader.TokenType}'.\");\n\n            JObject jo = JObject.Load(reader);\n            var matrix = new Matrix4x4();\n            matrix.m00 = jo[\"m00\"]?.Value<float>() ?? 0f;\n            matrix.m01 = jo[\"m01\"]?.Value<float>() ?? 0f;\n            matrix.m02 = jo[\"m02\"]?.Value<float>() ?? 0f;\n            matrix.m03 = jo[\"m03\"]?.Value<float>() ?? 0f;\n            matrix.m10 = jo[\"m10\"]?.Value<float>() ?? 0f;\n            matrix.m11 = jo[\"m11\"]?.Value<float>() ?? 0f;\n            matrix.m12 = jo[\"m12\"]?.Value<float>() ?? 0f;\n            matrix.m13 = jo[\"m13\"]?.Value<float>() ?? 0f;\n            matrix.m20 = jo[\"m20\"]?.Value<float>() ?? 0f;\n            matrix.m21 = jo[\"m21\"]?.Value<float>() ?? 0f;\n            matrix.m22 = jo[\"m22\"]?.Value<float>() ?? 0f;\n            matrix.m23 = jo[\"m23\"]?.Value<float>() ?? 0f;\n            matrix.m30 = jo[\"m30\"]?.Value<float>() ?? 0f;\n            matrix.m31 = jo[\"m31\"]?.Value<float>() ?? 0f;\n            matrix.m32 = jo[\"m32\"]?.Value<float>() ?? 0f;","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/CoplayDev/unity-mcp/blob/c21bf496bca87d54e75bad048563c3adb1782081/MCPForUnity/Runtime/Serialization/UnityTypeConverters.cs#L227-L263","documentation":"Thrown by Matrix4x4Converter.ReadJson when the current JSON token is not StartObject and not Null. Matrix4x4 must be deserialized from a JSON object with m00-m33 fields (or null for a zero matrix). Arrays, scalars, or strings are rejected. This differs from the Vector converters which accept arrays.","triggerScenarios":"Deserializing a Matrix4x4 field from a JSON array (e.g. [[..],[..],..]) or a scalar value. The converter only accepts object form with m00-m33 keys or JSON null. Passing a nested array of 16 floats triggers this.","commonSituations":"Client sends matrix as a flat or nested array of 16 floats; AI model outputs a 4x4 grid as arrays; confusion with the Vector converters which DO accept arrays; shader TRS matrix sent in array form.","solutions":["Send Matrix4x4 as a JSON object with m00-m33 keys: {\"m00\": 1, \"m01\": 0, ..., \"m33\": 1}.","For an identity matrix, send null (resolves to zero matrix) or build the full object.","Do NOT use array form for Matrix4x4 (unlike Vector2/3/4 which accept arrays).","If passing a TRS matrix, serialize it as an object with all 16 named elements."],"exampleFix":"// before\nparams = {\"matrix\": [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]}\n// after\nparams = {\"matrix\": {\"m00\":1,\"m01\":0,\"m02\":0,\"m03\":0,\"m10\":0,\"m11\":1,\"m12\":0,\"m13\":0,\"m20\":0,\"m21\":0,\"m22\":1,\"m23\":0,\"m30\":0,\"m31\":0,\"m32\":0,\"m33\":1}}","handlingStrategy":"type-guard","validationCode":"def is_valid_matrix4x4(val) -> bool:\n    # Matrix4x4 MUST be an object with m00-m33, NOT an array\n    if not isinstance(val, dict):\n        return False\n    expected = {f'm{r}{c}' for r in range(4) for c in range(4)}\n    return expected.issubset(val.keys())\n\n# Identity matrix template:\ndef identity_matrix():\n    m = {}\n    for r in range(4):\n        for c in range(4):\n            m[f'm{r}{c}'] = 1.0 if r == c else 0.0\n    return m","typeGuard":"function isMatrix4x4(val: unknown): val is Record<string, number> | null {\n  if (val === null) return true;\n  if (!val || typeof val !== 'object' || Array.isArray(val)) return false;\n  const keys = ['m00','m01','m02','m03','m10','m11','m12','m13','m20','m21','m22','m23','m30','m31','m32','m33'];\n  return keys.every(k => k in (val as Record<string, unknown>));\n}","tryCatchPattern":"try\n{\n    var matrix = serializer.Deserialize<Matrix4x4>(reader);\n}\ncatch (JsonSerializationException ex) when (ex.Message.Contains(\"Expected JSON object or null when deserializing Matrix4x4\"))\n{\n    return new ErrorResponse(\"Matrix4x4 must be a JSON object with m00-m33 keys, not an array.\");\n}","preventionTips":["Matrix4x4 uses object form only (unlike Vector converters which accept arrays).","Include all 16 keys m00-m33 in the object.","Send null for a zero matrix.","Don't pass nested arrays for matrices — use the named-element object form."],"tags":["serialization","matrix4x4","json","deserialization","type-converter"],"backgroundTag":null,"analyzedSha":"c21bf496bca87d54e75bad048563c3adb1782081","analyzedAt":"2026-08-13T17:36:56.095Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}