apache/seatunnel · error · UnsupportedOperationException

Please invoke DeserializationSchema#deserialize(byte[], Coll

Error message

Please invoke DeserializationSchema#deserialize(byte[], Collector<SeaTunnelRow>) instead.

What it means

OggJsonDeserializationSchema deliberately does not implement the single-argument deserialize(byte[]) method: Ogg messages must be routed through the collector-based overload so update events can emit multiple rows (update-before + update-after). Calling the byte[]-only variant always throws UnsupportedOperationException as an API-usage guard.

Source

Thrown at seatunnel-formats/seatunnel-format-json/src/main/java/org/apache/seatunnel/format/json/ogg/OggJsonDeserializationSchema.java:116

            String database,
            String table,
            boolean ignoreParseErrors) {
        this.catalogTable = catalogTable;
        this.seaTunnelRowType = catalogTable.getSeaTunnelRowType();
        this.jsonDeserializer =
                new JsonDeserializationSchema(catalogTable, false, ignoreParseErrors);
        this.database = database;
        this.table = table;
        this.fieldNames = seaTunnelRowType.getFieldNames();
        this.fieldCount = seaTunnelRowType.getTotalFields();
        this.ignoreParseErrors = ignoreParseErrors;
        this.databasePattern = database == null ? null : Pattern.compile(database);
        this.tablePattern = table == null ? null : Pattern.compile(table);
    }

    @Override
    public SeaTunnelRow deserialize(byte[] message) throws IOException {
        throw new UnsupportedOperationException(
                "Please invoke DeserializationSchema#deserialize(byte[], Collector<SeaTunnelRow>) instead.");
    }

    @Override
    public SeaTunnelDataType<SeaTunnelRow> getProducedType() {
        return this.seaTunnelRowType;
    }

    public void deserializeMessage(
            byte[] message, Collector<SeaTunnelRow> out, TablePath tablePath) {

        if (message == null || message.length == 0) {
            // skip tombstone messages
            return;
        }

        ObjectNode jsonNode;
        try {

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Call deserialize(byte[] message, Collector<SeaTunnelRow> out) instead — update the caller to the collector API
  2. If the caller API only offers byte[]-only deserialization, wrap with a small buffering collector that captures emitted rows
  3. Switch to a format whose single-row deserialize is implemented, if multi-row emission isn't needed

Example fix

// before
SeaTunnelRow row = oggSchema.deserialize(message);
// after
List<SeaTunnelRow> rows = new ArrayList<>();
oggSchema.deserialize(message, rows::add);
Defensive patterns

Strategy: try-catch

Try / catch

try {
    oggSchema.deserialize(message, collector); // collector-based API only
} catch (UnsupportedOperationException e) {
    // wrong API used; never happens with collector overload
    throw new AssertionError(e);
}

Prevention

When it happens

Trigger: A caller (custom code, tests, or a framework adapter) invokes DeserializationSchema.deserialize(byte[]) directly on an OggJsonDeserializationSchema instance instead of deserialize(byte[], Collector<SeaTunnelRow>).

Common situations: Writing a custom SourceReader that uses the simple deserialize API; adapting SeaTunnel formats in Flink-style pipelines; copy-pasting generic deserialization code that ignores the collector contract.

Related errors


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