apache/seatunnel · error · IllegalArgumentException

Unrecognized row kind:" + rowKind.toString()

Error message

Unrecognized row kind:" + rowKind.toString()

What it means

parseDeleteSign maps a SeaTunnel RowKind to SelectDB's DORIS delete sign value: INSERT/UPDATE_AFTER map to '0' (not deleted), DELETE/UPDATE_BEFORE map to '1' (deleted). Any other RowKind (or a null RowKind falling through) throws this IllegalArgumentException.

Solutions

  1. Inspect the upstream source/transform producing the row and ensure RowKind is explicitly set to INSERT/DELETE/UPDATE_BEFORE/UPDATE_AFTER
  2. Log or dump row.getRowKind() upstream to identify the unexpected kind
  3. If a new RowKind must be supported, add a branch to parseDeleteSign

Example fix

// before
// row created without RowKind, defaults unexpectedly
// after
row.setRowKind(RowKind.INSERT); // or DELETE/UPDATE_BEFORE/UPDATE_BEFORE before writing
Defensive patterns

Strategy: validation

Validate before calling

EnumSet.of(RowKind.INSERT, RowKind.DELETE, RowKind.UPDATE_BEFORE, RowKind.UPDATE_AFTER).contains(row.getRowKind())

Try / catch

try { sign = parseDeleteSign(rowKind); } catch (IllegalArgumentException e) { log.error("Unsupported RowKind: {}", rowKind); throw e; }

Prevention

When it happens

Trigger: A SeaTunnelRow with a RowKind outside the four handled values (e.g. a null RowKind or a newly added kind) reaches the serializer during CDC writing.

Common situations: Custom sources emitting rows without RowKind set; connector translation bugs producing unexpected row kinds; upstream CDC framework changes introducing new kinds not handled here.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at seatunnel-connectors-v2/connector-selectdb-cloud/src/main/java/org/apache/seatunnel/connectors/selectdb/serialize/SeaTunnelRowSerializer.java:104

        StringJoiner joiner = new StringJoiner(fieldDelimiter);
        for (int i = 0; i < row.getFields().length; i++) {
            Object field = convert(seaTunnelRowType.getFieldType(i), row.getField(i));
            String value = field != null ? field.toString() : NULL_VALUE;
            joiner.add(value);
        }
        if (enableDelete) {
            joiner.add(parseDeleteSign(row.getRowKind()));
        }
        return joiner.toString();
    }

    public String parseDeleteSign(RowKind rowKind) {
        if (RowKind.INSERT.equals(rowKind) || RowKind.UPDATE_AFTER.equals(rowKind)) {
            return "0";
        } else if (RowKind.DELETE.equals(rowKind) || RowKind.UPDATE_BEFORE.equals(rowKind)) {
            return "1";
        } else {
            throw new IllegalArgumentException("Unrecognized row kind:" + rowKind.toString());
        }
    }

    public static Builder builder() {
        return new Builder();
    }

    /** Builder for RowDataSerializer. */
    public static class Builder {
        private SeaTunnelRowType seaTunnelRowType;
        private String type;
        private String fieldDelimiter;
        private boolean deletable;

        public Builder setType(String type) {
            this.type = type;
            return this;
        }

View on GitHub (pinned to cf67b549a7)