apache/seatunnel · error · SeaTunnelJsonFormatException
UNSUPPORTED_OPERATION
UNSUPPORTED_OPERATION
Error message
Unsupported operation %s for row kind.
What it means
Thrown by OggJsonSerializationSchema.rowKind2String when converting a SeaTunnelRow's RowKind into the OGG operation string. Only INSERT, UPDATE_AFTER (mapped to insert), UPDATE_BEFORE and DELETE (mapped to delete) are handled; any other RowKind reaches the default branch and throws SeaTunnelJsonFormatException with UNSUPPORTED_OPERATION.
Source
Thrown at seatunnel-formats/seatunnel-format-json/src/main/java/org/apache/seatunnel/format/json/ogg/OggJsonSerializationSchema.java:109
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[] {"before", "after", "op_type", "table", "op_ts"},
new SeaTunnelDataType[] {
databaseSchema, databaseSchema, STRING_TYPE, STRING_TYPE, LONG_TYPE
});
}
}
View on GitHub (pinned to cf67b549a7)
Solutions
- Check what RowKind the upstream source/transform produces and make it emit only INSERT/UPDATE_AFTER/UPDATE_BEFORE/DELETE
- Insert a transform/filter stage that normalizes or drops rows with unsupported RowKind
- Use a different serialization format (e.g. canal-json or debezium-json) if the pipeline carries CDC kinds outside OGG's model
Example fix
// before SeaTunnelRow row = new SeaTunnelRow(...); // RowKind left unsupported // after row.setRowKind(RowKind.INSERT); // or UPDATE_AFTER / DELETE serialize(row);
Defensive patterns
Strategy: type-guard
Validate before calling
if (row.getRowKind() != RowKind.INSERT && row.getRowKind() != RowKind.UPDATE_AFTER
&& row.getRowKind() != RowKind.UPDATE_BEFORE && row.getRowKind() != RowKind.DELETE) {
throw new IllegalArgumentException("RowKind not serializable to ogg-json: " + row.getRowKind());
} Type guard
boolean isOggSerializableKind(RowKind kind) {
return kind == RowKind.INSERT || kind == RowKind.UPDATE_AFTER
|| kind == RowKind.UPDATE_BEFORE || kind == RowKind.DELETE;
} Try / catch
try {
byte[] bytes = schema.serialize(row);
} catch (SeaTunnelJsonFormatException e) {
log.warn("Unsupported RowKind {} for ogg-json sink", row.getRowKind(), e);
// normalize or drop the row
} Prevention
- Normalize RowKind in a transform immediately before the sink
- Only use ogg-json serialization for pipelines whose sources emit standard CDC kinds
- Add unit tests asserting the RowKind your source/transform emits
When it happens
Trigger: Serializing a row whose RowKind is not one of INSERT, UPDATE_AFTER, UPDATE_BEFORE, DELETE — e.g. a SeaTunnelRow constructed programmatically by a custom transform or connector emitting an exotic kind, then passed to serialize.
Common situations: Custom Source/Transform producing rows with unexpected RowKind; pipeline wiring where a CDC connector emits kinds the Ogg serializer was not designed for; unit tests building rows with a default/unsupported RowKind.
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
- COMMON-02
- UNSUPPORTED_OPERATION
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/20cb66df5cb34a96.
Report an issue: GitHub.