apache/seatunnel · error · UnsupportedOperationException

Unsupported operation '%s' for row kind.

Error message

Unsupported operation '%s' for row kind.

What it means

DebeziumJsonSerializationSchema converts a SeaTunnelRow to Debezium-envelope JSON by switching on row.getRowKind(); supported kinds are mapped to Debezium 'op' values. An unsupported RowKind (commonly null or an unexpected kind) falls into the default branch and throws UnsupportedOperationException, then gets wrapped by CommonError.jsonOperationError.

Source

Thrown at seatunnel-formats/seatunnel-format-json/src/main/java/org/apache/seatunnel/format/json/debezium/DebeziumJsonSerializationSchema.java:115

                    }
                    return jsonSerializer.serialize(genericRow);
                case UPDATE_BEFORE:
                    if (mergeUpdateEventFlag) {
                        cacheUpdateBeforeRow = row;
                        return null;
                    }
                case DELETE:
                    genericRow.setField(0, row);
                    genericRow.setField(1, null);
                    genericRow.setField(2, OP_DELETE);
                    genericRow.setField(3, source);
                    if (row.getOptions() != null
                            && row.getOptions().containsKey(EVENT_TIME.getName())) {
                        genericRow.setField(4, row.getOptions().get(EVENT_TIME.getName()));
                    }
                    return jsonSerializer.serialize(genericRow);
                default:
                    throw new UnsupportedOperationException(
                            String.format(
                                    "Unsupported operation '%s' for row kind.", row.getRowKind()));
            }
        } catch (Throwable t) {
            throw CommonError.jsonOperationError(FORMAT, row.toString(), t);
        }
    }

    private static SeaTunnelRowType createJsonRowType(SeaTunnelRowType databaseSchema) {
        return new SeaTunnelRowType(
                new String[] {"before", "after", "op", "source", "ts_ms"},
                new SeaTunnelDataType[] {
                    databaseSchema,
                    databaseSchema,
                    STRING_TYPE,
                    new MapType<>(BasicType.STRING_TYPE, BasicType.STRING_TYPE),
                    LONG_TYPE
                });

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Set a supported RowKind on every row before serialization (INSERT, UPDATE_BEFORE/UPDATE_AFTER, DELETE)
  2. Extend the serializer's switch if a new RowKind must be supported and rebuild the format module
  3. Log row.getRowKind() and the row contents (already embedded in the jsonOperationError message) to locate the producer
  4. Pin format and engine versions so RowKind enums match

Example fix

// before
SeaTunnelRow row = new SeaTunnelRow(2); // RowKind null -> default branch throws
// after
row.setRowKind(RowKind.INSERT);
byte[] json = serializer.serialize(row);
Defensive patterns

Strategy: validation

Validate before calling

RowKind kind = row.getRowKind();
if (kind == null) throw new IllegalArgumentException("RowKind must be set before Debezium serialization");

Type guard

boolean isDebeziumSerializable(SeaTunnelRow row) {
    RowKind k = row != null ? row.getRowKind() : null;
    return k != null; // extend to the explicit set of kinds the serializer supports
}

Try / catch

try {
    byte[] json = serializer.serialize(row);
} catch (UnsupportedOperationException e) {
    log.error("Cannot serialize row kind {} to Debezium JSON", row.getRowKind(), e);
    throw e;
}

Prevention

When it happens

Trigger: Calling serialize(row) on a row whose RowKind is not one of the kinds the schema maps (e.g. RowKind never set, or a kind added in newer SeaTunnel versions not handled here). The existing SOURCE shows it reachable from testSerializationDeserialization with such a row.

Common situations: Rows from custom sources without setRowKind; new RowKind values introduced upstream that the serializer's switch does not cover; test fixtures constructing rows with default/null 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


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