apache/seatunnel · error · IllegalStateException

Unknown operation type '${op}'.

Error message

Unknown operation type '${op}'.

What it means

Canal JSON events carry an 'op' field (INSERT/UPDATE/DELETE/QUERY/CREATE/ALTER are recognized). When op holds any other value, the deserializer's switch falls through to default and throws IllegalStateException. The enclosing catch re-wraps it via CommonError.jsonOperationError unless ignoreParseErrors is enabled.

Source

Thrown at seatunnel-formats/seatunnel-format-json/src/main/java/org/apache/seatunnel/format/json/canal/CanalJsonDeserializationSchema.java:210

                        out.collect(before);
                        out.collect(after);
                    }
                    break;
                case OP_DELETE:
                    for (int i = 0; i < dataNode.size(); i++) {
                        SeaTunnelRow row = convertJsonNode(dataNode.get(i));
                        row.setRowKind(RowKind.DELETE);
                        if (tablePath != null && !tablePath.toString().isEmpty()) {
                            row.setTableId(tablePath.toString());
                        }
                        if (tsNode != null) {
                            MetadataUtil.setEventTime(row, tsNode.asLong());
                        }
                        out.collect(row);
                    }
                    break;
                default:
                    throw new IllegalStateException(
                            String.format("Unknown operation type '%s'.", op));
            }
        } catch (RuntimeException e) {
            if (!ignoreParseErrors) {
                throw CommonError.jsonOperationError(FORMAT, jsonNode.toString(), e);
            }
        }
    }

    private ObjectNode convertBytes(byte[] message) throws SeaTunnelRuntimeException {
        if (message == null || message.length == 0) {
            return null;
        }

        try {
            return (ObjectNode) jsonDeserializer.deserializeToJsonNode(message);
        } catch (Throwable t) {
            if (!ignoreParseErrors) {

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Identify the unexpected op value in the message (logged in the jsonOperationError) and check your Canal server version for new op types
  2. Upgrade SeaTunnel's seatunnel-format-json to a version supporting the new Canal op types
  3. Filter or route unknown-op messages upstream before feeding the deserializer
  4. Set json.ignore-parse-errors=true to skip unparseable messages instead of failing the job

Example fix

// before (config)
json {
  ignore-parse-errors = false
}
// after
json {
  ignore-parse-errors = true
  timestamp-format.standard = "SQL"
}
Defensive patterns

Strategy: validation

Validate before calling

String op = node.path("op").asText("");
if (!op.matches("INSERT|UPDATE|DELETE|QUERY|CREATE|ALTER")) {
    throw new IllegalStateException("Unrecognized Canal op: " + op);
}

Type guard

boolean knownOp = Set.of("INSERT","UPDATE","DELETE","QUERY","CREATE","ALTER").contains(node.path("op").asText(""));

Try / catch

try { canalJsonSchema.deserialize(message, out); } catch (SeaTunnelJsonFormatException e) { log.warn("Skipping message with unknown op"); /* or rethrow depending on ignore-parse-errors */ }

Prevention

When it happens

Trigger: Consuming a Canal JSON message whose op field contains an unrecognized value (new Canal op types, corrupted op field, non-Canal JSON injected into the stream, or truncated/garbled messages).

Common situations: Canal version introducing new op codes not yet supported by this SeaTunnel format; unrelated producers writing to the same topic/queue; message corruption or charset issues mangling the op field.

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