karatelabs/karate · error · JsErrorException

Cannot convert a BigInt to a number

Error message

Cannot convert a BigInt to a number

What it means

`Number.prototype.toString(radix)` runs its radix argument through ToIntegerOrInfinity, which must reject BigInt values per the ES spec. Karate throws this TypeError when a BigInt (java.math.BigInteger) is passed as the radix instead of a regular number.

Solutions

  1. Convert the BigInt to a regular number first: `(255).toString(Number(radix))`
  2. Write BigInt literals without the `n` suffix when you intend a numeric radix
  3. Validate `typeof radix === 'number'` before calling toString

Example fix

// before
(255).toString(16n); // TypeError
// after
(255).toString(Number(16n));
Defensive patterns

Strategy: validation

Validate before calling

if (typeof radix !== 'number' || !Number.isInteger(radix)) { throw new Error('radix must be a plain integer number, got ' + typeof radix); }

Type guard

function isNumberRadix(r) { return typeof r === 'number' && Number.isInteger(r); }

Try / catch

try {
  s = n.toString(radix);
} catch (e) {
  if (String(e.message).includes('BigInt')) {
    s = n.toString(Number(radix));
  } else throw e;
}

Prevention

When it happens

Trigger: `(255).toString(bigIntValue)` where the radix came from BigInt arithmetic like `2n ** 4n`; passing a BigInt parsed from JSON or Karate variable interpolation as the radix.

Common situations: Mixed BigInt/number arithmetic in tests where the radix was computed with BigInt literals; data-driven tests where a JSON/CSV value became a BigInt.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/3bf730a0a8cbaeb1. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/JsNumberPrototype.java:58

    private JsNumberPrototype() {
        super(JsObjectPrototype.INSTANCE);
        install("toFixed", 1, this::toFixed);
        install("toPrecision", 1, this::toPrecision);
        install("toExponential", 1, this::toExponential);
        install("toLocaleString", 0, this::toLocaleString);
        install("toString", 1, this::toStringMethod);
        install("valueOf", 0, this::valueOf);
    }

    private Object toStringMethod(Context context, Object[] args) {
        Number n = thisNumber(context);
        // Spec: only `undefined` (or absent) defaults to radix 10; `null` runs through
        // ToInteger → 0 → RangeError.
        if (args.length > 0 && args[0] != Terms.UNDEFINED) {
            // ToIntegerOrInfinity rejects BigInt — spec mandates TypeError.
            if (args[0] instanceof java.math.BigInteger) {
                throw JsErrorException.typeError("Cannot convert a BigInt to a number");
            }
            int radix = Terms.objectToNumber(args[0]).intValue();
            if (radix < 2 || radix > 36) {
                throw JsErrorException.rangeError("toString() radix must be between 2 and 36");
            }
            if (radix != 10) {
                double d = n.doubleValue();
                if (d == Math.floor(d) && !Double.isInfinite(d)) {
                    return Long.toString((long) d, radix);
                }
                return Double.toString(d);
            }
        }
        return Terms.numberToString(n);
    }

    /**
     * Spec {@code thisNumberValue} §21.1.3: unwrap JsNumber, accept primitive

View on GitHub (pinned to a22eb90246)