{"record":{"id":"31b096d15019417d","repo":"apache/seatunnel","slug":"unknown-operation-type-op-31b096","errorCode":null,"errorMessage":"Unknown operation type '${op}'.","messagePattern":"Unknown operation type '(.+?)'\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"seatunnel-formats/seatunnel-format-json/src/main/java/org/apache/seatunnel/format/json/debezium/DebeziumJsonDeserializationSchema.java","lineNumber":179,"sourceCode":"                out.collect(after);\n                break;\n            case OP_DELETE:\n                SeaTunnelRow delete = debeziumRowConverter.parse(payload.get(DATA_BEFORE));\n                if (delete == null) {\n                    throw new IllegalStateException(\n                            String.format(REPLICA_IDENTITY_EXCEPTION, \"DELETE\"));\n                }\n                delete.setRowKind(RowKind.DELETE);\n                if (tablePath != null) {\n                    delete.setTableId(tablePath.toString());\n                }\n                if (tsNode != null) {\n                    MetadataUtil.setEventTime(delete, tsNode.asLong());\n                }\n                out.collect(delete);\n                break;\n            default:\n                throw new IllegalStateException(format(\"Unknown operation type '%s'.\", op));\n        }\n    }\n\n    @Override\n    public SeaTunnelDataType<SeaTunnelRow> getProducedType() {\n        return this.rowType;\n    }\n\n    private JsonNode getPayload(JsonNode jsonNode) {\n        if (debeziumEnabledSchema) {\n            return jsonNode.get(DATA_PAYLOAD);\n        }\n        return jsonNode;\n    }\n}\n","sourceCodeStart":161,"sourceCodeEnd":195,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-formats/seatunnel-format-json/src/main/java/org/apache/seatunnel/format/json/debezium/DebeziumJsonDeserializationSchema.java#L161-L195","documentation":"Debezium change events carry an 'op' field ('c' create, 'u' update, 'd' delete, 'r' read/snapshot). parsePayload switches on this value and throws IllegalStateException for anything else, since SeaTunnel cannot map an unknown operation to a RowKind. This guards against malformed, corrupted, or forward-incompatible Debezium messages.","triggerScenarios":"A message JSON reaching parsePayload whose op field is missing, null, empty, or an unexpected value (e.g. 't' truncate, 'm' message, or a corrupted character).","commonSituations":"Non-data change events (truncate, heartbeat/message events) flowing through the CDC topic; Debezium version drift producing new op values; hand-crafted or test payloads missing 'op'; Kafka topic routing delivering non-change-event envelopes.","solutions":["Inspect the offending message's 'op' value and confirm it is one of c/u/d/r","Filter unsupported event types (truncate/message) using Debezium SMTs or topic routing","Enable the format's ignoreParseErrors option if skipping unparseable messages is acceptable","Align SeaTunnel and Debezium versions so the set of supported ops matches"],"exampleFix":"// before: raw topic includes truncate events (op='t') -> parse fails\n// after: drop them upstream with a Debezium SMT / RegexRouter\n\"transforms\": \"route\",\n\"transforms.route.type\": \"org.apache.kafka.connect.transforms.RegexRouter\",\n\"transforms.route.regex\": \"cdc_(.*)\",\n\"transforms.route.replacement\": \"$1\"","handlingStrategy":"try-catch","validationCode":"JsonNode op = payload.get(\"op\");\nif (op == null || !\"cudr\".contains(op.asText(\"\"))) {\n    // skip or route to DLQ before parsing\n}","typeGuard":null,"tryCatchPattern":"try {\n    deserializer.deserialize(message, out);\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"Unknown operation type\")) {\n        log.warn(\"Skipping unsupported Debezium op: {}\", e.getMessage());\n        return; // or send to DLQ\n    }\n    throw e;\n}","preventionTips":["Filter non-data events (truncate/message) with SMTs or topic routing","Enable ignoreParseErrors for tolerant pipelines","Keep Debezium and SeaTunnel format versions aligned"],"tags":["cdc","debezium","unknown-operation","payload"],"backgroundTag":"unsupported-enum-value","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}