{"record":{"id":"ef51300b0cd58111","repo":"apache/pulsar","slug":"current-size-and-other-size-not-equals","errorCode":null,"errorMessage":"Current size and other size not equals","messagePattern":"Current size and other size not equals","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/MultiMessageIdImpl.java","lineNumber":69,"sourceCode":"    }\n\n    // If all messageId in map are same size, and all bigger/smaller than the other, return valid value.\n    @Override\n    public int compareTo(MessageId o) {\n        if (!(o instanceof MultiMessageIdImpl)) {\n            throw new IllegalArgumentException(\n                \"expected MultiMessageIdImpl object. Got instance of \" + o.getClass().getName());\n        }\n\n        MultiMessageIdImpl other = (MultiMessageIdImpl) o;\n        Map<String, MessageId> otherMap = other.getMap();\n\n        if ((map == null || map.isEmpty()) && (otherMap == null || otherMap.isEmpty())) {\n            return 0;\n        }\n\n        if (otherMap == null || map == null || otherMap.size() != map.size()) {\n            throw new IllegalArgumentException(\"Current size and other size not equals\");\n        }\n\n        int result = 0;\n        for (Entry<String, MessageId> entry : map.entrySet()) {\n            MessageId otherMessage = otherMap.get(entry.getKey());\n            if (otherMessage == null) {\n                throw new IllegalArgumentException(\n                    \"Other MessageId not have topic \" + entry.getKey());\n            }\n\n            int currentResult = entry.getValue().compareTo(otherMessage);\n            if (result == 0) {\n                result = currentResult;\n            } else if (currentResult == 0) {\n                continue;\n            } else if (result != currentResult) {\n                throw new IllegalArgumentException(\n                    \"Different MessageId in Map get different compare result\");","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/MultiMessageIdImpl.java#L51-L87","documentation":"MultiMessageIdImpl.compareTo requires both multi-ids to cover the same number of topics/partitions; if either map is null or their sizes differ it throws IllegalArgumentException('Current size and other size not equals'). A position across partitions can only be ordered element-wise when the partition sets match.","triggerScenarios":"Comparing two MultiMessageIdImpl built from different numbers of partitions — typically after the partitioned topic was resized (more partitions added) between the two snapshots, or one snapshot came from an empty/null map.","commonSituations":"Checkpoint restore after increasing partition count of a partitioned topic; comparing an early empty cursor with a later full one; mixing cursors from differently configured topics.","solutions":["Re-checkpoint cursors after any partition-count change; don't compare cursors taken before/after a partition resize","Handle the extra partitions explicitly: drop them from the newer cursor or default the missing ones to earliest/latest before comparing","If comparing for resume logic, compare only the intersection of topics and treat missing topics as earliest","Catch IllegalArgumentException and rebuild the cursor from per-partition state"],"exampleFix":"// before\nint r = oldCursor.compareTo(newCursor); // throws if partition counts differ\n// after\nMap<String, MessageId> oldMap = oldCursor.getMap();\nMap<String, MessageId> newMap = newCursor.getMap();\nif (oldMap.size() != newMap.size()) {\n    // topic was re-partitioned; rebuild cursor for current partition count\n    oldMap = rebuildCursorForCurrentPartitions(newMap.keySet());\n}\nint r = oldCursor.compareTo(newCursor);","handlingStrategy":"validation","validationCode":"boolean canCompare(MultiMessageIdImpl a, MultiMessageIdImpl b) {\n    return a.getMap() != null && b.getMap() != null\n        && a.getMap().size() == b.getMap().size();\n}","typeGuard":"boolean samePartitionCount(MultiMessageIdImpl a, MultiMessageIdImpl b) {\n    return a.getMap().size() == b.getMap().size();\n}","tryCatchPattern":"try {\n    int r = a.compareTo(b);\n} catch (IllegalArgumentException e) {\n    // topic re-partitioned: rebuild cursors for the current partition count\n}","preventionTips":["Re-checkpoint cursors after any partition-count change","Never compare cursors captured before and after a re-partitioning without migration","Build cursors from the current topic partition list, not from stale stored maps"],"tags":["pulsar","messageid","partitioned","compareto","illegal-argument"],"backgroundTag":"messageid-partition-count-mismatch","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}