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

  1. Check what RowKind the upstream source/transform produces and make it emit only INSERT/UPDATE_AFTER/UPDATE_BEFORE/DELETE
  2. Insert a transform/filter stage that normalizes or drops rows with unsupported RowKind
  3. 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

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


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