{"record":{"id":"41eb2087226139d8","repo":"apache/beam","slug":"expected-json-object-for-field-name-instead-got-jsonnodetype","errorCode":null,"errorMessage":"Expected JSON object for field '{name}'. Instead got {jsonNodeType}","messagePattern":"Expected JSON object for field '(.+?)'\\. Instead got (.+?)","errorType":"validation","errorClass":"UnsupportedRowJsonException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/util/RowJson.java","lineNumber":387,"sourceCode":"                + \"'. Instead got \"\n                + arrayFieldValue.jsonNodeType().name());\n      }\n\n      return arrayFieldValue\n          .jsonArrayElements()\n          .map(\n              jsonArrayElement ->\n                  extractJsonNodeValue(\n                      FieldValue.of(\n                          arrayFieldValue.name() + \"[]\",\n                          arrayFieldValue.arrayElementType(),\n                          jsonArrayElement)))\n          .collect(toImmutableList());\n    }\n\n    private Map<String, Object> jsonObjectToMap(FieldValue mapFieldValue) {\n      if (!mapFieldValue.isJsonObject()) {\n        throw new UnsupportedRowJsonException(\n            \"Expected JSON object for field '\"\n                + mapFieldValue.name()\n                + \"'. Instead got \"\n                + mapFieldValue.jsonNodeType().name());\n      }\n\n      Map<String, Object> result = new HashMap<>();\n      Iterator<Map.Entry<String, JsonNode>> fields = mapFieldValue.jsonValue().fields();\n      while (fields.hasNext()) {\n        Map.Entry<String, JsonNode> field = fields.next();\n        String key = field.getKey();\n        JsonNode value = field.getValue();\n\n        Object extractedValue =\n            extractJsonNodeValue(\n                FieldValue.of(\n                    mapFieldValue.name() + \"['\" + key + \"']\", mapFieldValue.mapValueType(), value));\n","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/util/RowJson.java#L369-L405","documentation":"For MAP-typed schema fields, jsonObjectToMap requires the JSON value to be an object whose keys become map keys. A different JSON node type causes UnsupportedRowJsonException that names the encountered Jackson node type.","triggerScenarios":"jsonToRow where a MAP<...> schema field receives a non-object JSON value, e.g. \"props\": \"k=v\" or an array instead of an object.","commonSituations":"Producers serializing maps as lists of key/value pairs; schema changed from array to map; generic JSON ingestion with mismatched reader schema.","solutions":["Emit the map field as a JSON object, e.g. \"props\": {\"k\": \"v\"}","Change the schema field type (e.g. to ARRAY<ROW<k,v>>) to match the payload","Convert list-of-pairs JSON to an object before parsing","Catch UnsupportedRowJsonException and route bad records to error handling"],"exampleFix":"// before\n{\"props\": [{\"k\":\"a\",\"v\":1}]}\n// after\n{\"props\": {\"a\": 1}}","handlingStrategy":"validation","validationCode":"JsonNode n = json.get(\"mapField\");\nif (n != null && !n.isObject()) throw new IllegalArgumentException(\"Map field must be a JSON object, got \" + n.getNodeType());","typeGuard":null,"tryCatchPattern":"try { Row r = RowJsonUtils.jsonToRow(mapper, json); } catch (RowJson.UnsupportedRowJsonException e) { /* handle */ }","preventionTips":["Serialize maps as JSON objects, not arrays of pairs","Document map encoding for producers","Validate payloads against MAP-typed fields"],"tags":["beam","json","map","deserialization"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}