{"record":{"id":"899f626b4d825441","repo":"karatelabs/karate","slug":"cannot-convert-a-bigint-to-a-number","errorCode":null,"errorMessage":"Cannot convert a BigInt to a number","messagePattern":"Cannot convert a BigInt to a number","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsBigIntPrototype.java","lineNumber":59,"sourceCode":"        install(\"toLocaleString\", 0, this::toStringMethod);\n    }\n\n    private Object toStringMethod(Context context, Object[] args) {\n        BigInteger n = asBigInt(context);\n        // Spec: only `undefined` (or absent) defaults to radix 10; `null` runs through\n        // ToInteger → 0 → RangeError. Same shape as Number.prototype.toString.\n        if (args.length > 0 && args[0] != Terms.UNDEFINED) {\n            Object radixArg = args[0];\n            // Object → ToPrimitive (hint \"number\"). If valueOf/toString are non-callable\n            // ToPrimitive throws TypeError (per spec); error flows through context for\n            // user-thrown valueOf bodies.\n            if (radixArg instanceof ObjectLike && context instanceof CoreContext cc) {\n                radixArg = Terms.toPrimitive(radixArg, \"number\", cc);\n                if (cc.isError()) return Terms.UNDEFINED;\n            }\n            // ToIntegerOrInfinity rejects BigInt — spec mandates TypeError before RangeError.\n            if (radixArg instanceof BigInteger) {\n                throw JsErrorException.typeError(\"Cannot convert a BigInt to a number\");\n            }\n            int radix = Terms.objectToNumber(radixArg).intValue();\n            if (radix < 2 || radix > 36) {\n                throw JsErrorException.rangeError(\"toString() radix must be between 2 and 36\");\n            }\n            return n.toString(radix);\n        }\n        return n.toString();\n    }\n\n    private Object valueOf(Context context, Object[] args) {\n        return asBigInt(context);\n    }\n\n    private static BigInteger asBigInt(Context context) {\n        Object thisObj = context.getThisObject();\n        if (thisObj instanceof JsBigInt jb) {\n            return jb.value;","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsBigIntPrototype.java#L41-L77","documentation":"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.","triggerScenarios":"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)).","commonSituations":"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.","solutions":["Pass a plain Number radix: x.toString(16) not x.toString(16n)","Convert with Number(radix) after confirming it is a small safe integer: x.toString(Number(radix))","Keep radix constants as JS numbers, not BigInt literals","Guard: if (typeof radix === 'bigint') radix = Number(radix)"],"exampleFix":"// before\nlet hex = value.toString(RADIX); // RADIX = 16n\n// after\nlet hex = value.toString(Number(RADIX)); // 16","handlingStrategy":"type-guard","validationCode":"function bigIntToString(n, radix) {\n  if (typeof radix === 'bigint') radix = Number(radix);\n  if (radix !== undefined && (!Number.isInteger(radix) || radix < 2 || radix > 36)) throw new RangeError('radix out of range');\n  return radix === undefined ? n.toString() : n.toString(radix);\n}","typeGuard":"const isNumberRadix = (r) => typeof r === 'number' && Number.isSafeInteger(r);","tryCatchPattern":"let s;\ntry { s = n.toString(radix); } catch (e) {\n  if (e instanceof TypeError && /BigInt to a number/.test(e.message)) s = n.toString(Number(radix));\n  else throw e;\n}","preventionTips":["Keep radix constants as plain Number literals (16, not 16n)","Coerce BigInt-derived values with Number() before using as radix","Never copy BigInt literals wholesale from generated/migrated code","Lint for BigInt literals used in numeric-parameter positions"],"tags":["javascript","bigint","type-error","tostring-radix"],"backgroundTag":"type-mismatch","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}