apache/seatunnel · error · UnsupportedOperationException

Unsupported rowKind: " + rowKind

Error message

Unsupported rowKind: " + rowKind

What it means

ReduceBufferedBatchStatementExecutor only supports CDC row kinds INSERT, DELETE, UPDATE_AFTER, and UPDATE_BEFORE; any other RowKind (e.g. INSERT-less custom kinds) reaching the changeFlag logic throws UnsupportedOperationException. It indicates an upstream produced a row kind the buffered CDC executor cannot classify.

Source

Thrown at seatunnel-connectors-v2/connector-clickhouse/src/main/java/org/apache/seatunnel/connectors/seatunnel/clickhouse/sink/client/executor/ReduceBufferedBatchStatementExecutor.java:114

    @Override
    public void closeStatements() throws SQLException {
        if (!buffer.isEmpty()) {
            executeBatch();
        }
        insertOrUpdateExecutor.closeStatements();
        deleteExecutor.closeStatements();
    }

    private boolean changeFlag(RowKind rowKind) {
        switch (rowKind) {
            case INSERT:
            case UPDATE_AFTER:
                return true;
            case DELETE:
            case UPDATE_BEFORE:
                return false;
            default:
                throw new UnsupportedOperationException("Unsupported rowKind: " + rowKind);
        }
    }
}

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Check the upstream source/transform for why a non-CDC RowKind is emitted and fix it there
  2. Ensure the source's CDC capability maps all events to supported INSERT/UPDATE_BEFORE/UPDATE_AFTER/DELETE kinds
  3. Upgrade the connector/SeaTunnel version where additional RowKinds may be supported
Defensive patterns

Strategy: type-guard

Validate before calling

// filter/normalize rows before the sink
if (row.getRowKind() != RowKind.INSERT && row.getRowKind() != RowKind.DELETE
 && row.getRowKind() != RowKind.UPDATE_BEFORE && row.getRowKind() != RowKind.UPDATE_AFTER)
  throw new IllegalStateException("unsupported RowKind for ClickHouse cdc sink: " + row.getRowKind());

Type guard

boolean isSupportedRowKind(SeaTunnelRow row) {
  switch (row.getRowKind()) {
    case INSERT: case DELETE: case UPDATE_BEFORE: case UPDATE_AFTER: return true;
    default: return false;
  }
}

Prevention

When it happens

Trigger: A SeaTunnelRow with a RowKind outside {INSERT, DELETE, UPDATE_BEFORE, UPDATE_AFTER} (e.g. custom/unmapped kinds) flows into the ClickHouse sink with support_upsert/cdc enabled, hitting the default branch of the switch in changeFlag.

Common situations: A source/transform upstream emits non-standard row kinds or a new RowKind added in a newer SeaTunnel version that this executor has not been extended to handle.

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/98d7fa24bb94b1b4. Report an issue: GitHub.