apache/seatunnel · error · SeaTunnelRuntimeException

COMMON-02

COMMON-02

Error message

Json JSON convert/parse '<payload>' operation failed.

What it means

OggJsonSerializationSchema.serialize() wraps the entire row-to-JSON conversion in a catch-all that rethrows via CommonError.jsonOperationError. This is thrown when any failure occurs while converting a SeaTunnelRow (including setting c/z/o/op/ts fields) into its OGG-flavored JSON string via the underlying JsonSerializationSchema. The original cause is attached as the throwable's cause.

Source

Thrown at seatunnel-formats/seatunnel-format-json/src/main/java/org/apache/seatunnel/format/json/ogg/OggJsonSerializationSchema.java:93

            if (mergeUpdateEventFlag && row.getRowKind() == RowKind.UPDATE_AFTER) {
                reuse.setField(0, cacheUpdateBeforeRow);
            } else {
                reuse.setField(0, null);
            }

            reuse.setField(1, row);
            reuse.setField(2, rowKind2String(row.getRowKind()));
            if (!StringUtils.isEmpty(row.getTableId())) {
                reuse.setField(3, row.getTableId());
            }

            if (row.getOptions() != null && row.getOptions().containsKey(EVENT_TIME.getName())) {
                reuse.setField(4, row.getOptions().get(EVENT_TIME.getName()));
            }
            return jsonSerializer.serialize(reuse);
        } catch (Throwable t) {
            throw CommonError.jsonOperationError(FORMAT, row.toString(), t);
        }
    }

    private String rowKind2String(RowKind rowKind) {
        switch (rowKind) {
            case INSERT:
            case UPDATE_AFTER:
                if (mergeUpdateEventFlag && rowKind.equals(RowKind.UPDATE_AFTER)) {
                    return OP_UPDATE;
                }
                return OP_INSERT;
            case UPDATE_BEFORE:
            case DELETE:
                return OP_DELETE;
            default:
                throw new SeaTunnelJsonFormatException(
                        CommonErrorCodeDeprecated.UNSUPPORTED_OPERATION,
                        String.format("Unsupported operation %s for row kind.", rowKind));

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Read the cause chain (t) printed with the error to find the real serialization failure (usually a type mismatch or null).
  2. Verify the catalog table's SeaTunnelRowType exactly matches the data being serialized (field names, count, types).
  3. Check for null fields where the schema expects non-null; sanitize or coalesce before serializing.
  4. Upgrade/check version compatibility between the OggJson format and the connector producing rows.
  5. Reproduce locally with the failing row (row.toString() appears in the message) and run through the serializer in a unit test.

Example fix

// before
row.setField(3, null); // nullable field not declared nullable
return schema.serialize(row); // throws jsonOperationError
// after
if (value == null) {
    value = ""; // or skip / use default per schema
}
row.setField(3, value);
return schema.serialize(row);
Defensive patterns

Strategy: try-catch

Validate before calling

if (row == null || row.getArity() != rowType.getTotalFields()) {
    throw new IllegalArgumentException("Row arity mismatch: expected " + rowType.getTotalFields());
}
for (int i = 0; i < row.getArity(); i++) {
    if (row.getField(i) == null && !rowType.getFieldType(i).nullable()) {
        throw new IllegalArgumentException("Null in non-nullable field " + i);
    }
}

Type guard

boolean isSerializableRow(SeaTunnelRow row, SeaTunnelRowType type) {
    return row != null && row.getArity() == type.getTotalFields();
}

Try / catch

try {
    byte[] json = schema.serialize(row);
} catch (Exception e) {
    log.error("OGG JSON serialize failed for row: {}", row, e);
    // route to dead-letter / skip
}

Prevention

When it happens

Trigger: Calling serialize(row) on a row whose schema/type doesn't match the declared SeaTunnelRowType (e.g. wrong field count, null in a non-nullable position, unsupported data type), or when the OGG JSON serializer hits an internal Jackson/serialization error. Observed raised from serialize() during a test run (runTest).

Common situations: Upstream CDC data (e.g. from an OGG message stream) contains types incompatible with the declared row schema; a null value written into a required field; mismatched SeaTunnelRow arity after schema evolution; malformed EVENT_TIME option value placement.

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/b32165ab2d840bc1. Report an issue: GitHub.