karatelabs/karate · error · JsErrorException
toString() radix must be between 2 and 36
Error message
toString() radix must be between 2 and 36
What it means
`Number.prototype.toString(radix)` requires the radix to be an integer between 2 and 36 inclusive. Karate throws this RangeError when ToIntegerOrInfinity of the radix falls outside that range (0, 1, negative, or > 36). Note `null`/`false` coerce to 0, so even they trigger it — only `undefined` or an absent argument defaults to 10.
Solutions
- Use a radix in 2–36: `(255).toString(16)`
- Omit the argument or pass `undefined` for decimal — do not pass null
- Clamp/validate before calling: `radix >= 2 && radix <= 36 ? n.toString(radix) : n.toString()`
Example fix
// before (255).toString(null); // RangeError: null coerces to 0 // after (255).toString(); // decimal, or (255).toString(10)
Defensive patterns
Strategy: validation
Validate before calling
if (radix !== undefined && !(Number.isInteger(radix) && radix >= 2 && radix <= 36)) { throw new Error('radix must be an integer 2-36'); } Type guard
function validRadix(r) { return r === undefined || (typeof r === 'number' && Number.isInteger(r) && r >= 2 && r <= 36); } Try / catch
try {
s = n.toString(radix);
} catch (e) {
if (String(e.message).includes('radix must be between 2 and 36')) {
s = n.toString(); // fall back to decimal
} else throw e;
} Prevention
- Omit the argument for decimal; don't pass null (coerces to 0)
- Clamp radix to [2, 36] before use
- Remember only undefined defaults to base 10 — not null/false/0
When it happens
Trigger: `(255).toString(1)`, `.toString(0)`, `.toString(37)`, `.toString(-2)`; passing `null` as the radix (null → ToInteger → 0 → RangeError); a radix variable computed out of bounds.
Common situations: Misunderstanding that null/false default the radix (they don't — only undefined does); algorithmically chosen bases (e.g. base-64 attempts); config-supplied radix values that are invalid.
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
- Cannot convert a BigInt to a number
- value must be >= 1
- Number.prototype method called on incompatible receiver
- toPrecision() precision must be between 1 and 100
- toExponential() fractionDigits must be between 0 and 100
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/2b47233f1554c664.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsNumberPrototype.java:62
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
* Number, TypeError otherwise. {@code Number.prototype} is a Number exotic
* with {@code [[NumberData]]} of +0, so it routes to 0.
*/
private static Number thisNumber(Context context) {View on GitHub (pinned to a22eb90246)