karatelabs/karate · error · JsErrorException (rangeError)

Division by zero

Error message

Division by zero

What it means

Karate's JS engine throws this RangeError when a BigInt division (the `/` operator with both operands as BigInt) has a zero divisor. IEEE 754 double division allows division by zero (yielding Infinity), but the BigInt spec mandates a RangeError. Terms.java implements the JS division operator and mirrors V8 behavior.

Solutions

  1. Guard the divisor before dividing: if (y === 0n) return 0n; or return a sentinel instead of dividing
  2. Cast to a normal number if BigInt precision is not required, so division by zero yields Infinity instead of throwing
  3. Wrap the expression in try/catch and treat RangeError as an 'undefined result' case

Example fix

// before (JS in Karate)
var ratio = totaln / countn;
// after
var ratio = countn === 0n ? 0n : totaln / countn;
Defensive patterns

Strategy: validation

Validate before calling

if (typeof divisor !== 'bigint') throw new Error('divisor must be BigInt');
if (divisor === 0n) throw new Error('divisor must be non-zero BigInt');

Type guard

function isNonZeroBigInt(v) { return typeof v === 'bigint' && v !== 0n; }

Try / catch

try { result = dividend / divisor; } catch (e) { if (String(e).includes('Division by zero')) result = 0n; else throw e; }

Prevention

When it happens

Trigger: Evaluating JS like `10n / 0n` or `x / y` where both operands are BigInt and y equals 0n via the embedded JS interpreter (karate-js Terms.div).

Common situations: JS expressions in Karate features or kjs scripts doing dynamic division where a computed BigInt divisor evaluates to zero (e.g. averaged counts, ratios with an empty denominator).

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 karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/4719e14f17ce91a4. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/Terms.java:759

        if (context != null && context.isError()) return UNDEFINED;
        if (isBigIntOp(lhs, rhs)) {
            requireBothBigInt(lhs, rhs, "*");
            return narrowBigInt(((BigInteger) lhs).multiply((BigInteger) rhs));
        }
        double result = lhs.doubleValue() * rhs.doubleValue();
        return narrow(result);
    }

    static Object div(Object lhsObject, Object rhsObject, CoreContext context) {
        Number lhs = toNumericOperand(lhsObject, context);
        if (context != null && context.isError()) return UNDEFINED;
        Number rhs = toNumericOperand(rhsObject, context);
        if (context != null && context.isError()) return UNDEFINED;
        if (isBigIntOp(lhs, rhs)) {
            requireBothBigInt(lhs, rhs, "/");
            BigInteger r = (BigInteger) rhs;
            if (r.signum() == 0) {
                throw JsErrorException.rangeError("Division by zero");
            }
            return narrowBigInt(((BigInteger) lhs).divide(r));
        }
        // no special-casing for zero / Infinity operands: IEEE 754 double division is
        // exactly what the spec's Number::divide mandates, and narrow() preserves -0.0
        double result = lhs.doubleValue() / rhs.doubleValue();
        return narrow(result);
    }

    static Object min(Object lhsObject, Object rhsObject, CoreContext context) {
        Number lhs = toNumericOperand(lhsObject, context);
        if (context != null && context.isError()) return UNDEFINED;
        Number rhs = toNumericOperand(rhsObject, context);
        if (context != null && context.isError()) return UNDEFINED;
        if (isBigIntOp(lhs, rhs)) {
            requireBothBigInt(lhs, rhs, "-");
            return narrowBigInt(((BigInteger) lhs).subtract((BigInteger) rhs));
        }

View on GitHub (pinned to a22eb90246)