apache/beam · error · UnsupportedRowJsonException

Expected JSON object for field '{name}'. Unable to convert '

Error message

Expected JSON object for field '{name}'. Unable to convert '{jsonValue}' to Beam Row, it is not a JSON object. Currently only JSON objects can be parsed to Beam Rows

What it means

When a schema field is itself a Row type, jsonObjectToRow requires the JSON value to be an object. If the value is any other JSON node type (string, number, array, etc.), UnsupportedRowJsonException is thrown because only JSON objects can be parsed into nested Beam Rows.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/util/RowJson.java:345

        } else if (SqlTypes.TIME.getIdentifier().equals(identifier)) {
          return timeValueExtractor().extractValue(fieldValue.jsonValue());
        } else if (SqlTypes.DATETIME.getIdentifier().equals(identifier)) {
          return localDatetimeValueExtractor().extractValue(fieldValue.jsonValue());
        } else {
          return extractJsonNodeValue(
              FieldValue.of(
                  fieldValue.name(),
                  fieldValue.type().getLogicalType().getBaseType(),
                  fieldValue.jsonValue()));
        }
      }

      return extractJsonPrimitiveValue(fieldValue);
    }

    private Row jsonObjectToRow(FieldValue rowFieldValue) {
      if (!rowFieldValue.isJsonObject()) {
        throw new UnsupportedRowJsonException(
            "Expected JSON object for field '"
                + rowFieldValue.name()
                + "'. Unable to convert '"
                + rowFieldValue.jsonValue().asText()
                + "' to Beam Row, it is not a JSON object. Currently only JSON objects can be parsed to Beam Rows");
      }

      return rowFieldValue.rowSchema().getFields().stream()
          .map(
              schemaField ->
                  extractJsonNodeValue(
                      FieldValue.of(
                          schemaField.getName(),
                          schemaField.getType(),
                          rowFieldValue.jsonFieldValue(schemaField.getName()))))
          .collect(toRow(rowFieldValue.rowSchema()));
    }

View on GitHub (pinned to 12126d8942)

Solutions

  1. Fix the JSON so the nested field is a JSON object matching the nested row schema
  2. Update the schema so the field type matches the actual JSON shape (e.g. ARRAY<ROW>)
  3. Transform the payload (wrap the value in an object) before parsing
  4. Catch UnsupportedRowJsonException and inspect/repair the offending field

Example fix

// before
{"nested": [1,2,3]}
// after
{"nested": {"a": 1, "b": 2}}
Defensive patterns

Strategy: validation

Validate before calling

JsonNode n = json.get("nestedFieldName");
if (n != null && !n.isObject()) throw new IllegalArgumentException("Nested row field must be a JSON object");

Try / catch

try { Row r = RowJsonUtils.jsonToRow(mapper, json); } catch (RowJson.UnsupportedRowJsonException e) { /* handle */ }

Prevention

When it happens

Trigger: jsonToRow where a nested-row schema field receives a non-object JSON value, e.g. "nested": "text" or "nested": [1,2] instead of an object.

Common situations: Nested data flattened differently upstream; producer emits an array of objects where a single object is expected; wrong schema version used on the reader side.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/d55c142e0463bff6. Report an issue: GitHub.