karatelabs/karate · error · JsErrorException

Cannot convert a BigInt to a number

Error message

Cannot convert a BigInt to a number

What it means

BigInt.prototype.toString(radix) rejects a BigInt radix argument with a TypeError because the spec's ToIntegerOrInfinity step cannot convert BigInt to Number. Karate's JS engine enforces this ordering deliberately (TypeError before any RangeError), as noted in the source comment.

Solutions

  1. Pass a plain Number radix: x.toString(16) not x.toString(16n)
  2. Convert with Number(radix) after confirming it is a small safe integer: x.toString(Number(radix))
  3. Keep radix constants as JS numbers, not BigInt literals
  4. Guard: if (typeof radix === 'bigint') radix = Number(radix)

Example fix

// before
let hex = value.toString(RADIX); // RADIX = 16n
// after
let hex = value.toString(Number(RADIX)); // 16
Defensive patterns

Strategy: type-guard

Validate before calling

function bigIntToString(n, radix) {
  if (typeof radix === 'bigint') radix = Number(radix);
  if (radix !== undefined && (!Number.isInteger(radix) || radix < 2 || radix > 36)) throw new RangeError('radix out of range');
  return radix === undefined ? n.toString() : n.toString(radix);
}

Type guard

const isNumberRadix = (r) => typeof r === 'number' && Number.isSafeInteger(r);

Try / catch

let s;
try { s = n.toString(radix); } catch (e) {
  if (e instanceof TypeError && /BigInt to a number/.test(e.message)) s = n.toString(Number(radix));
  else throw e;
}

Prevention

When it happens

Trigger: x.toString(2n), x.toString(radixBig) where radix was itself computed as a BigInt (e.g. from BigInt arithmetic or parsed as a BigInt literal), n.toString(BigInt(16)).

Common situations: Mixed BigInt/Number math pipelines where the radix variable was derived from BigInt operations; porting code where literals became 16n instead of 16; generated code emitting BigInt literals for all numeric constants.

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/899f626b4d825441. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/JsBigIntPrototype.java:59

        install("toLocaleString", 0, this::toStringMethod);
    }

    private Object toStringMethod(Context context, Object[] args) {
        BigInteger n = asBigInt(context);
        // Spec: only `undefined` (or absent) defaults to radix 10; `null` runs through
        // ToInteger → 0 → RangeError. Same shape as Number.prototype.toString.
        if (args.length > 0 && args[0] != Terms.UNDEFINED) {
            Object radixArg = args[0];
            // Object → ToPrimitive (hint "number"). If valueOf/toString are non-callable
            // ToPrimitive throws TypeError (per spec); error flows through context for
            // user-thrown valueOf bodies.
            if (radixArg instanceof ObjectLike && context instanceof CoreContext cc) {
                radixArg = Terms.toPrimitive(radixArg, "number", cc);
                if (cc.isError()) return Terms.UNDEFINED;
            }
            // ToIntegerOrInfinity rejects BigInt — spec mandates TypeError before RangeError.
            if (radixArg instanceof BigInteger) {
                throw JsErrorException.typeError("Cannot convert a BigInt to a number");
            }
            int radix = Terms.objectToNumber(radixArg).intValue();
            if (radix < 2 || radix > 36) {
                throw JsErrorException.rangeError("toString() radix must be between 2 and 36");
            }
            return n.toString(radix);
        }
        return n.toString();
    }

    private Object valueOf(Context context, Object[] args) {
        return asBigInt(context);
    }

    private static BigInteger asBigInt(Context context) {
        Object thisObj = context.getThisObject();
        if (thisObj instanceof JsBigInt jb) {
            return jb.value;

View on GitHub (pinned to a22eb90246)