{"record":{"id":"38a426c17d3336e7","repo":"apache/seatunnel","slug":"received-operation-skip","errorCode":null,"errorMessage":"Received {} operation, skip","messagePattern":"Received (.+?) operation, skip","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/debezium/row/SeaTunnelRowDebeziumDeserializeSchema.java","lineNumber":312,"sourceCode":"            MetadataUtil.setBinlogFile(before, binlogFile);\n            MetadataUtil.setBinlogPos(before, binlogPos);\n            MetadataUtil.setBinlogRow(before, binlogRow);\n            MetadataUtil.setGtid(before, gtid);\n            collector.collect(before);\n\n            SeaTunnelRow after = extractAfterRow(converters, record, messageStruct, valueSchema);\n            after.setRowKind(RowKind.UPDATE_AFTER);\n            after.setTableId(tableId);\n            MetadataUtil.setDelay(after, delay);\n            MetadataUtil.setEventTime(after, fetchTimestamp);\n            MetadataUtil.setSourceTimestamp(after, messageTimestamp);\n            MetadataUtil.setBinlogFile(after, binlogFile);\n            MetadataUtil.setBinlogPos(after, binlogPos);\n            MetadataUtil.setBinlogRow(after, binlogRow);\n            MetadataUtil.setGtid(after, gtid);\n            collector.collect(after);\n        } else {\n            log.warn(\"Received {} operation, skip\", operation);\n        }\n    }\n\n    private SeaTunnelRow extractAfterRow(\n            SeaTunnelRowDebeziumDeserializationConverters runtimeConverter,\n            SourceRecord record,\n            Struct value,\n            Schema valueSchema)\n            throws Exception {\n\n        Schema afterSchema = valueSchema.field(Envelope.FieldName.AFTER).schema();\n        Struct after = value.getStruct(Envelope.FieldName.AFTER);\n        return runtimeConverter.convert(record, after, afterSchema);\n    }\n\n    private SeaTunnelRow extractBeforeRow(\n            SeaTunnelRowDebeziumDeserializationConverters runtimeConverter,\n            SourceRecord record,","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/debezium/row/SeaTunnelRowDebeziumDeserializeSchema.java#L294-L330","documentation":"A Debezium change record carried an operation type the data-record path does not emit (the handled branches cover insert/read/update-after). deserializeDataChangeRecord logs this warning with the operation name and returns without collecting a row, so the record produces no downstream output.","triggerScenarios":"deserializeDataChangeRecord receives an Operation outside the handled insert/read/update branches — typically TRUNCATE, or a DELETE whose handling path is not enabled by the configured delete-handling mode, or a heartbeat/message record routed to the data path.","commonSituations":"Running TRUNCATE TABLE on a CDC-monitored table; Debezium heartbeat events reaching the deserializer; connectors where delete handling is disabled and DELETE ops fall into the skip branch; replication events the deserializer version does not recognize.","solutions":["Identify the operation from the warning; TRUNCATE and heartbeat skips are usually benign.","If DELETE rows are being skipped unexpectedly, enable/fix the delete-handling mode (e.g. support delete events / tombstone handling) in the deserializer configuration.","Avoid TRUNCATE on monitored tables or implement truncate propagation in a custom deserializer.","Filter heartbeat/tombstone records out of the source table list so they never reach the data path.","Compare source vs sink row counts to confirm no real data loss is hidden behind these skips."],"exampleFix":"// before\n} else {\n    log.warn(\"Received {} operation, skip\", operation);\n}\n// after: explicitly handle truncate, log others at debug\n} else if (operation == Operation.TRUNCATE) {\n    log.info(\"Received TRUNCATE for {}, not propagated\", record.topic());\n} else {\n    log.warn(\"Received {} operation, skip\", operation);\n}","handlingStrategy":"fallback","validationCode":"// pre-filter non-emittable operations so they never reach the data path\nString opName = record.valueSchema().name();\nif (opName.endsWith(\"TransactionMetadata\") || opName.endsWith(\"Heartbeat\")) {\n    return;\n}","typeGuard":"boolean isEmittable(Operation op) {\n    return op == Operation.CREATE || op == Operation.READ || op == Operation.UPDATE;\n}","tryCatchPattern":"// this path does not throw; guard on the emitted row instead\nif (row == null) {\n    log.debug(\"Record skipped due to operation {}\", operation);\n    return;\n}\ncollector.collect(row);","preventionTips":["Avoid TRUNCATE on CDC-monitored tables, or handle truncates explicitly in a custom deserializer.","Exclude heartbeat/tombstone records from the source table list.","Treat this warning as informational unless source/sink row counts diverge.","Upgrade the connector if your database emits operations the deserializer does not recognize."],"tags":["cdc","debezium","skip-record","data-loss"],"backgroundTag":"unsupported-operation","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}