apache/seatunnel · error · SeaTunnelJsonFormatException
UNSUPPORTED_OPERATION
UNSUPPORTED_OPERATION
Error message
Unsupported operation %s for row kind.
What it means
MaxWellJsonSerializationSchema.rowKind2String maps a SeaTunnelRow's RowKind to a Maxwell operation string (insert/delete). RowKinds outside INSERT / UPDATE_BEFORE / DELETE (e.g. UPDATE_AFTER) fall to the default branch and throw UNSUPPORTED_OPERATION, because Maxwell JSON has no representation for that operation.
Source
Thrown at seatunnel-formats/seatunnel-format-json/src/main/java/org/apache/seatunnel/format/json/maxwell/MaxWellJsonSerializationSchema.java:111
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));
}
}
private static SeaTunnelRowType createJsonRowType(SeaTunnelRowType databaseSchema) {
return new SeaTunnelRowType(
new String[] {"old", "data", "type", "database", "table", "ts"},
new SeaTunnelDataType[] {
databaseSchema, databaseSchema, STRING_TYPE, STRING_TYPE, STRING_TYPE, LONG_TYPE
});
}
}
View on GitHub (pinned to cf67b549a7)
Solutions
- Insert a transform or use a sink format that supports update events (e.g. canal-json/debezium-json output)
- Coalesce update pairs before the sink so rows are INSERT or DELETE kinds only
- Check the upstream source configuration to avoid emitting unsupported RowKinds into this sink
- If Maxwell-JSON must be used, pre-convert updates to delete+insert manually
Example fix
// before: CDC source (update pairs) -> MaxwellJson sink => throw
// after: use a format that models updates
sink {
Kafka {
format = canal-json
}
} Defensive patterns
Strategy: type-guard
Validate before calling
if (row.getRowKind() != RowKind.INSERT && row.getRowKind() != RowKind.UPDATE_BEFORE && row.getRowKind() != RowKind.DELETE) {
throw new IllegalArgumentException("RowKind " + row.getRowKind() + " not serializable as maxwell-json");
} Type guard
boolean isMaxwellSerializable(RowKind kind) {
return kind == RowKind.INSERT || kind == RowKind.UPDATE_BEFORE || kind == RowKind.DELETE;
} Try / catch
try {
serializer.serialize(row, out);
} catch (SeaTunnelJsonFormatException e) {
log.error("Row kind not representable in maxwell json: {}", e.getMessage());
throw e;
} Prevention
- Don't wire update-emitting CDC sources directly to maxwell-json sinks
- Use canal-json/debezium-json sink formats when updates must be represented
- Coalesce update pairs upstream (e.g. via deduplicate/transform)
When it happens
Trigger: serialize() is called with a SeaTunnelRow whose RowKind is e.g. UPDATE_AFTER — typical when a transform or upstream source emits row kinds the Maxwell serializer never anticipated into a sink configured with format=maxwell-json.
Common situations: Chaining a CDC source (which emits UPDATE_BEFORE/UPDATE_AFTER pairs) directly to a Maxwell-JSON sink; transforms that change row kind; custom connectors producing unusual row kinds.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Unrecognized row kind:<rowKind>
- COMMON_UNSUPPORTED_OPERATION
- UNSUPPORTED_OPERATION
- UNSUPPORTED_OPERATION
- Unknown row kind: ${rowKind}
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/7f8fdf05d92e9b28.
Report an issue: GitHub.