{"record":{"id":"def4b8ae4f727966","repo":"apache/seatunnel","slug":"illegal-argument-def4b8","errorCode":"ILLEGAL_ARGUMENT","errorMessage":"MongoDB CDC data change record has no value: ","messagePattern":"MongoDB CDC data change record has no value: ","errorType":"error_code","errorClass":"MongodbConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-mongodb/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/mongodb/utils/MongodbRecordUtils.java","lineNumber":82,"sourceCode":"\n    /** Check the sourceRecord is snapshot record. */\n    public static boolean isSnapshotRecord(SourceRecord sourceRecord) {\n        return \"true\".equals(getOffsetValue(sourceRecord, COPY_KEY_FIELD));\n    }\n\n    /** Check the sourceRecord is heartbeat event. */\n    public static boolean isHeartbeatEvent(SourceRecord sourceRecord) {\n        return \"true\".equals(getOffsetValue(sourceRecord, HEARTBEAT_KEY_FIELD));\n    }\n\n    public static boolean isDataChangeRecord(SourceRecord sourceRecord) {\n        return !isWatermarkEvent(sourceRecord) && !isHeartbeatEvent(sourceRecord);\n    }\n\n    public static @Nonnull OperationType getOperationType(@Nonnull SourceRecord sourceRecord) {\n        Struct value = (Struct) sourceRecord.value();\n        if (value == null) {\n            throw new MongodbConnectorException(\n                    ILLEGAL_ARGUMENT,\n                    \"MongoDB CDC data change record has no value: \" + sourceRecord);\n        }\n\n        String operationType = null;\n        if (value.schema().field(OPERATION_TYPE) != null) {\n            operationType = value.getString(OPERATION_TYPE);\n        }\n        if (StringUtils.isEmpty(operationType)) {\n            if (isSnapshotRecord(sourceRecord)) {\n                return OperationType.INSERT;\n            }\n            throw new MongodbConnectorException(\n                    ILLEGAL_ARGUMENT,\n                    \"MongoDB CDC data change record has no operationType field: \" + sourceRecord);\n        }\n        return OperationType.fromString(operationType);\n    }","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-cdc/connector-cdc-mongodb/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/mongodb/utils/MongodbRecordUtils.java#L64-L100","documentation":"MongodbRecordUtils.getOperationType reads the Debezium-style SourceRecord's value Struct to determine the change operation. If the record's value is null it cannot classify the change and throws ILLEGAL_ARGUMENT — a null value normally means a tombstone, which this connector does not treat as a valid change event.","triggerScenarios":"sourceRecord.value() returns null (tombstone record emitted after a delete, or a heartbeat/schema-change record with no payload) and is passed to getOperationType.","commonSituations":"Kafka-connect-style tombstones enabled so deletes emit a second null-value record; connector version emitting record kinds the utility was not designed for; a misrouted record from a different topic/stream reaching this code.","solutions":["Skip records whose value is null before calling getOperationType (tombstones carry no change data)","Filter out non-data events with MongodbRecordUtils.isWatermarkEvent/isHeartbeatEvent before processing","Disable tombstone emission at the source if null-value records are not expected"],"exampleFix":"// before\nOperationType op = MongodbRecordUtils.getOperationType(sourceRecord);\n// after\nif (sourceRecord.value() == null) {\n    return; // tombstone / non-data record\n}\nOperationType op = MongodbRecordUtils.getOperationType(sourceRecord);","handlingStrategy":"validation","validationCode":"if (sourceRecord == null || sourceRecord.value() == null) {\n    return; // tombstone / non-data record, skip\n}","typeGuard":"boolean isDataRecord(SourceRecord r) {\n    return r != null && r.value() instanceof Struct\n        && !MongodbRecordUtils.isWatermarkEvent(r) && !MongodbRecordUtils.isHeartbeatEvent(r);\n}","tryCatchPattern":"try {\n    OperationType op = MongodbRecordUtils.getOperationType(record);\n} catch (MongodbConnectorException e) {\n    log.warn(\"Skipping record without value: {}\", record.topic());\n}","preventionTips":["Filter tombstone (null-value) records before classification","Exclude watermark/heartbeat events from change processing","Route only MongoDB CDC data records into getOperationType"],"tags":["mongodb","cdc","source-record","null-value"],"backgroundTag":"empty-required-field","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"}