apache/seatunnel · warning · ArithmeticException

byte overflow

Error message

byte overflow

What it means

ObjectUtils.plus adds an int to a numeric value while preserving the original type (Byte, Short, Integer, Long...). For Byte (and Short) it promotes to int, adds, and throws ArithmeticException('byte overflow') if the result no longer fits the original type's range ([-128, 127] for byte). This protects against silent narrowing truncation.

Solutions

  1. Use a wider accumulator type (int/long) before incrementing, or start from a widened value
  2. Cap the increment so the result stays in range, or wrap-around explicitly if wrap is intended
  3. Catch ArithmeticException at the call site and switch to a wider type for the remainder of the computation

Example fix

// before
Object pos = ObjectUtils.plus(cursor, batchSize); // cursor is Byte -> may overflow
// after
long pos = ((Number) cursor).longValue() + batchSize; // widen before adding
Defensive patterns

Strategy: type-guard

Validate before calling

if (number instanceof Byte || number instanceof Short) {
  long projected = number.longValue() + (long) augend;
  long max = number instanceof Byte ? Byte.MAX_VALUE : Short.MAX_VALUE;
  if (projected > max) throw new IllegalStateException("Widen accumulator before incrementing");
}

Type guard

boolean canPlusWithoutOverflow(Number n, int augend) {
  long r = n.longValue() + augend;
  return n instanceof Byte ? (r >= Byte.MIN_VALUE && r <= Byte.MAX_VALUE)
       : n instanceof Short ? (r >= Short.MIN_VALUE && r <= Short.MAX_VALUE)
       : n instanceof Integer ? (r >= Integer.MIN_VALUE && r <= Integer.MAX_VALUE)
       : true;
}

Try / catch

try {
  Object result = ObjectUtils.plus(number, augend);
} catch (ArithmeticException e) {
  // widen: long v = ((Number) number).longValue() + augend;
}

Prevention

When it happens

Trigger: Calling ObjectUtils.plus with a Byte value whose sum with augend leaves byte range — e.g. plus((byte)100, 100) or incrementing a byte-typed counter repeatedly until it exceeds 127.

Common situations: Cursor/offset arithmetic on a column value stored as TINYINT that keeps incrementing past 127; batch position tracking initialized from a byte-typed DB value; algorithmic loops using plus on small-typed accumulators.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/utils/ObjectUtils.java:34

 */

package org.apache.seatunnel.connectors.seatunnel.jdbc.utils;

import java.math.BigDecimal;
import java.math.BigInteger;

public class ObjectUtils {
    /**
     * Returns a number {@code Object} whose value is {@code (number + augend)}, Note: This method
     * will throw {@link ArithmeticException} if number overflows.
     */
    public static Object plus(Object number, int augend) throws ArithmeticException {
        if (number instanceof Byte) {
            // Byte and Short are promoted to int before addition; check their own ranges
            // before narrowing the result back to the original type.
            int result = Math.addExact((Byte) number, augend);
            if (result < Byte.MIN_VALUE || result > Byte.MAX_VALUE) {
                throw new ArithmeticException("byte overflow");
            }
            return (byte) result;
        } else if (number instanceof Short) {
            int result = Math.addExact((Short) number, augend);
            if (result < Short.MIN_VALUE || result > Short.MAX_VALUE) {
                throw new ArithmeticException("short overflow");
            }
            return (short) result;
        } else if (number instanceof Integer) {
            return Math.addExact((Integer) number, augend);
        } else if (number instanceof Long) {
            return Math.addExact((Long) number, augend);
        } else if (number instanceof Float) {
            return ((Float) number) + augend;
        } else if (number instanceof Double) {
            return ((Double) number) + augend;
        } else if (number instanceof BigInteger) {
            return ((BigInteger) number).add(BigInteger.valueOf(augend));

View on GitHub (pinned to cf67b549a7)