apache/seatunnel · error · IllegalArgumentException

String range left boundary

Error message

String range left boundary [%s] must not be greater than right boundary [%s]

What it means

AsciiStringRangeSplitter.split requires left <= right lexicographically because it converts boundaries to BigInteger values to interpolate split points. If the left boundary compares greater than the right, no ascending range can be produced, so it throws IllegalArgumentException naming both boundaries.

Solutions

  1. Swap the boundaries so the lexicographically smaller value is passed as left.
  2. Fix the code that derives min/max from the database to order them before splitting.
  3. Normalize case/padding of boundaries before calling the splitter.

Example fix

// before
splitter.split("Z", "A");
// after
splitter.split("A", "Z");
Defensive patterns

Strategy: validation

Validate before calling

if (left.compareTo(right) > 0) {
  String t = left; left = right; right = t; // normalize order before split
}

Prevention

When it happens

Trigger: Calling split(left, right) with left.compareTo(right) > 0, e.g. split("Z", "A") or boundaries swapped when constructing ranges from queried min/max values.

Common situations: Swapped min/max from a query that returns them in unexpected order; manual config of split ranges with reversed endpoints; case-sensitivity surprises where uppercase 'Z' < lowercase 'a' makes user-supplied bounds reversed.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/4d912b8314d75577. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/source/AsciiStringRangeSplitter.java:46

    private AsciiStringRangeSplitter() {}

    // This mapping is order-preserving only for fixed-length printable ASCII strings under a
    // binary collation. Other shapes must be rejected and handled by hash or single splitting.
    static String[] split(String left, String right, int expectSliceNumber) {
        if (left == null || right == null) {
            throw new IllegalArgumentException("String range boundary cannot be null");
        }
        validateRangeBoundary(left, "left");
        validateRangeBoundary(right, "right");
        if (left.length() != right.length()) {
            throw new IllegalArgumentException(
                    "String range split requires fixed-length ASCII boundaries");
        }
        if (left.equals(right)) {
            return new String[] {left, right};
        }
        if (left.compareTo(right) > 0) {
            throw new IllegalArgumentException(
                    String.format(
                            "String range left boundary [%s] must not be greater than right boundary [%s]",
                            left, right));
        }

        BigInteger[] splitValues =
                splitBigInteger(
                        stringToBigInteger(left), stringToBigInteger(right), expectSliceNumber);
        String[] result = new String[splitValues.length];
        result[0] = left;
        result[splitValues.length - 1] = right;
        for (int i = 1; i < splitValues.length - 1; i++) {
            result[i] = bigIntegerToString(splitValues[i], left.length());
            validateRangeBoundary(result[i], "generated");
        }
        validateLexicalOrder(result);
        return result;
    }

View on GitHub (pinned to cf67b549a7)