{"record":{"id":"c87ad8c85ed48441","repo":"apache/beam","slug":"the-partitions-s-and-s-have-no-overlap","errorCode":null,"errorMessage":"The partitions %s and %s have no overlap","messagePattern":"The partitions (.+?) and (.+?) have no overlap","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/changestreams/ByteStringRangeHelper.java","lineNumber":299,"sourceCode":"    return ByteString.unsignedLexicographicalComparator()\n                .compare(partition.getStart(), partition.getEnd())\n            < 0\n        || partition.getEnd().isEmpty();\n  }\n\n  /**\n   * Return the overlapping parts of 2 partitions. Throw IllegalArgumentException if the 2\n   * partitions don't overlap at all.\n   *\n   * @param p1 first partition\n   * @param p2 second partition\n   * @return the intersection of the 2 partitions\n   * @throws IllegalArgumentException if the 2 partitions don't overlap at all\n   */\n  public static ByteStringRange getIntersectingPartition(ByteStringRange p1, ByteStringRange p2)\n      throws IllegalArgumentException {\n    if (!doPartitionsOverlap(p1, p2)) {\n      throw new IllegalArgumentException(\n          String.format(\n              \"The partitions %s and %s have no overlap\",\n              formatByteStringRange(p1), formatByteStringRange(p2)));\n    }\n    ByteString start = p1.getStart();\n    ByteString end = p1.getEnd();\n    if (compareStartKey(start, p2.getStart()) < 0) {\n      start = p2.getStart();\n    }\n    if (compareEndKey(end, p2.getEnd()) > 0) {\n      end = p2.getEnd();\n    }\n    return ByteStringRange.create(start, end);\n  }\n}\n","sourceCodeStart":281,"sourceCodeEnd":315,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/changestreams/ByteStringRangeHelper.java#L281-L315","documentation":"ByteStringRangeHelper.getIntersectingPartition computes the overlap of two Bigtable change-stream partitions (key ranges). If doPartitionsOverlap reports the two ByteStringRange partitions are disjoint, it throws IllegalArgumentException naming both formatted ranges, because an intersection would be empty/undefined.","triggerScenarios":"Calling getIntersectingPartition(p1, p2) with ranges that do not overlap — e.g. computing the intersection of a partition with a sibling partition after a split, or with a stale partition whose keys were reassigned.","commonSituations":"Bigtable change-stream connector internals: resuming a stream against a partition whose boundaries changed after an automatic tablet split/merge, or mixing partitions from different snapshots/watermark states.","solutions":["Before intersecting, call doPartitionsOverlap(p1, p2) and handle the non-overlapping case explicitly.","Ensure the partition comes from the same stream run/snapshot; re-read the current partition from the metadata table.","Check for tablet split/merge events and refresh partition metadata before computing intersections."],"exampleFix":"// before\nByteStringRange inter = ByteStringRangeHelper.getIntersectingPartition(p1, p2);\n// after\nif (ByteStringRangeHelper.doPartitionsOverlap(p1, p2)) {\n  ByteStringRange inter = ByteStringRangeHelper.getIntersectingPartition(p1, p2);\n} else { /* refresh partition metadata */ }","handlingStrategy":"try-catch","validationCode":"if (!ByteStringRangeHelper.doPartitionsOverlap(p1, p2)) {\n  throw new IllegalStateException(\"Refusing to intersect non-overlapping partitions \" + p1 + \" / \" + p2);\n}","typeGuard":null,"tryCatchPattern":"try {\n  ByteStringRange inter = ByteStringRangeHelper.getIntersectingPartition(p1, p2);\n} catch (IllegalArgumentException e) {\n  // partitions are disjoint: refresh partition metadata from the metadata table and retry once\n  partitions = metadataTableDao.getPartitionsForStream(streamId);\n}","preventionTips":["Always verify overlap with doPartitionsOverlap before intersecting.","Refresh partition state after tablet splits/merges before computing intersections.","Use partitions from a single consistent stream run/snapshot."],"tags":["bigtable","changestream","partition","range-overlap"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}