alibaba/DataX · error · IllegalArgumentException

对 BigInteger 进行切分时,其左右区间不能为 null. 此处:left=[%s],right=[%s].

Error message

对 BigInteger 进行切分时,其左右区间不能为 null. 此处:left=[%s],right=[%s].

What it means

RangeSplitUtil.doBigIntegerSplit throws IllegalArgumentException when either the left or right boundary BigInteger is null. The splitter needs concrete numeric endpoints to compute sub-ranges; null endpoints indicate the caller failed to derive a range (e.g. from a null splitPk value).

Source

Thrown at common/src/main/java/com/alibaba/datax/common/util/RangeSplitUtil.java:50

    public static long[] doLongSplit(long left, long right, int expectSliceNumber) {
        BigInteger[] result = doBigIntegerSplit(BigInteger.valueOf(left),
                BigInteger.valueOf(right), expectSliceNumber);
        long[] returnResult = new long[result.length];
        for (int i = 0, len = result.length; i < len; i++) {
            returnResult[i] = result[i].longValue();
        }
        return returnResult;
    }

    public static BigInteger[] doBigIntegerSplit(BigInteger left, BigInteger right, int expectSliceNumber) {
        if (expectSliceNumber < 1) {
            throw new IllegalArgumentException(String.format(
                    "切分份数不能小于1. 此处:expectSliceNumber=[%s].", expectSliceNumber));
        }

        if (null == left || null == right) {
            throw new IllegalArgumentException(String.format(
                    "对 BigInteger 进行切分时,其左右区间不能为 null. 此处:left=[%s],right=[%s].", left, right));
        }

        if (left.compareTo(right) == 0) {
            return new BigInteger[]{left, right};
        } else {
            // 调整大小顺序,确保 left < right
            if (left.compareTo(right) > 0) {
                BigInteger temp = left;
                left = right;
                right = temp;
            }

            //left < right
            BigInteger endAndStartGap = right.subtract(left);

            BigInteger step = endAndStartGap.divide(BigInteger.valueOf(expectSliceNumber));
            BigInteger remainder = endAndStartGap.remainder(BigInteger.valueOf(expectSliceNumber));

View on GitHub (pinned to 80ec23d5c5)

Solutions

  1. Pick a splitPk column that is NOT NULL (ideally indexed) — a primary key.
  2. If the range cannot be determined, skip splitting and run a single channel instead of calling the splitter.
  3. Guard at the call site: if (left == null || right == null) fall back to a non-split task.

Example fix

// before
BigInteger[] points = RangeSplitUtil.doBigIntegerSplit(min, max, n);

// after
if (min == null || max == null) {
    // single-task fallback, no split
    return Collections.singletonList(new Range(defaultLeft, defaultRight));
}
BigInteger[] points = RangeSplitUtil.doBigIntegerSplit(min, max, n);
Defensive patterns

Strategy: type-guard

Validate before calling

if (minBig == null || maxBig == null) {
    return singleTaskFallback(); // no split
}
return RangeSplitUtil.doBigIntegerSplit(minBig, maxBig, n);

Type guard

static boolean hasValidRange(BigInteger l, BigInteger r) {
    return l != null && r != null;
}

Try / catch

catch (IllegalArgumentException e) when message mentions null: skip splitting, run one task.

Prevention

When it happens

Trigger: Calling doBigIntegerSplit(null, x, n) or doBigIntegerSplit(x, null, n). In practice: a splitPk column whose min/max could not be read (all-null column, query failure silently swallowed) yields null endpoints that reach this method.

Common situations: Choosing a splitPk column that is nullable and entirely NULL in the source table; reader plugins that return null when the range query returns no rows.

Related errors


AI-assisted analysis of alibaba/DataX@80ec23d5c5 (2026-08-14). Data as JSON: /api/errors/28f5592b79624d48. Report an issue: GitHub.