{"record":{"id":"c4bcf778df82c74b","repo":"alibaba/canal","slug":"skipping-path","errorCode":null,"errorMessage":"skipping path","messagePattern":"skipping path","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/JsonDiffConversion.java","lineNumber":57,"sourceCode":"    public static StringBuilder print_json_diff(LogBuffer buffer, long len, String columnName, int columnIndex,\n                                                String charsetName) {\n        return print_json_diff(buffer, len, columnName, columnIndex, Charset.forName(charsetName));\n    }\n\n    public static StringBuilder print_json_diff(LogBuffer buffer, long len, String columnName, int columnIndex,\n                                                Charset charset) {\n        int position = buffer.position();\n        List<String> operation_names = new ArrayList<>();\n        while (buffer.hasRemaining()) {\n            int operation_int = buffer.getUint8();\n            if (operation_int >= JSON_DIFF_OPERATION_COUNT) {\n                throw new IllegalArgumentException(\"reading operation type (invalid operation code)\");\n            }\n\n            // skip path\n            long path_length = buffer.getPackedLong();\n            if (path_length > len) {\n                throw new IllegalArgumentException(\"skipping path\");\n            }\n\n            // compute operation name\n            byte[] lastP = buffer.getData(buffer.position() + (int) path_length - 1, 1);\n            String operation_name = json_diff_operation_name(operation_int, lastP[0]);\n            operation_names.add(operation_name);\n\n            buffer.forward((int) path_length);\n            // skip value\n            if (operation_int != DIFF_OPERATION_REMOVE) {\n                long value_length = buffer.getPackedLong();\n                if (value_length > len) {\n                    throw new IllegalArgumentException(\"skipping path\");\n                }\n\n                buffer.forward((int) value_length);\n            }\n","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/JsonDiffConversion.java#L39-L75","documentation":"Thrown during the first pass of JSON diff parsing when the packed-long path length exceeds the total diff payload length (len). After reading the operation code, the code reads a variable-length packed integer for the path length; if this path_length is greater than the overall diff size, the data is corrupt or misaligned.","triggerScenarios":"Calling print_json_diff() where, after reading a valid operation code, the path_length obtained from buffer.getPackedLong() exceeds the len parameter. This means the declared path would extend beyond the diff payload boundary.","commonSituations":"Binlog corruption truncating the diff payload, buffer position offset from an earlier parse consuming too few or too many bytes, or a malformed JSON partial update event from a bug in the MySQL server or an intermediate proxy that modifies binlog events.","solutions":["Verify the len parameter passed to print_json_diff matches the actual column value length from the row event.","Trace buffer position from the row event header to ensure no prior column consumed incorrect byte counts.","Hex-dump the diff payload region to inspect the packed path_length value.","Skip the corrupt diff and re-synchronize replication from the last known-good binlog position."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// The library checks path_length > len internally.\n// Callers can pre-validate by ensuring the diff payload length matches the column value size.\nif (len > buffer.remaining()) {\n    logger.warn(\"Diff payload length {} exceeds buffer remaining {}\", len, buffer.remaining());\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    JsonDiffConversion.print_json_diff(buffer, len, columnName, columnIndex, charset);\n} catch (IllegalArgumentException e) {\n    logger.warn(\"JSON diff path length exceeds payload in column {}, pos={}\", columnName, buffer.position(), e);\n}","preventionTips":["Verify the len parameter passed to print_json_diff exactly matches the column value length from the row event.","Ensure buffer position is correctly set to the start of the diff payload before calling print_json_diff."],"tags":["json-diff","binlog","mysql","buffer-bounds","packed-long"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}