karatelabs/karate · error · JsErrorException
toExponential() fractionDigits must be between 0 and 100
Error message
toExponential() fractionDigits must be between 0 and 100
What it means
Number.prototype.toExponential accepts fractionDigits in the range 0–100 in this engine (spec max is 100). A provided (non-undefined) digit count outside that range raises a RangeError before any formatting.
Solutions
- Clamp digits to 0–100 before calling
- Use 0 or omit the argument for automatic minimum digits
- Switch to toPrecision if 1+ significant digits were intended
Example fix
// before var s = n.toExponential(-1); // after var s = n.toExponential(Math.min(100, Math.max(0, d)));
Defensive patterns
Strategy: validation
Validate before calling
if (d != null && (d < 0 || d > 100)) throw new RangeError('fractionDigits must be 0..100'); Type guard
function isValidFractionDigits(d) { return d == null || (typeof d === 'number' && Number.isInteger(d) && d >= 0 && d <= 100); } Try / catch
try { s = n.toExponential(d); } catch (e) { if (e instanceof RangeError) { s = n.toExponential(Math.min(100, Math.max(0, d))); } else { throw e; } } Prevention
- Clamp computed digit counts to 0–100
- Use undefined (not -1) for automatic digit selection
- Note the 0 floor differs from toPrecision's 1
When it happens
Trigger: Calling n.toExponential(d) with d < 0 or d > 100, typically a computed or misremembered digit count; passing -1 intending 'auto'.
Common situations: Porting from toPrecision (whose floor is 1) or other engines; dynamically derived digit counts; typos like toExponential(-1).
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
- toPrecision() precision must be between 1 and 100
- render() needs at least one argument
- render() read arg should not be null
- karate.driver can only be read within a scenario
- karate.setup() is not available in this context
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/890d6b2779dc0d68.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsNumberPrototype.java:181
if (args.length > 0 && args[0] instanceof java.math.BigInteger) {
throw JsErrorException.typeError("Cannot convert a BigInt to a number");
}
boolean digitsAbsent = args.length == 0 || args[0] == Terms.UNDEFINED;
int digits = digitsAbsent ? 0 : toIntegerArg(args[0], context);
if (Double.isNaN(d)) return "NaN";
if (d == Double.POSITIVE_INFINITY) return "Infinity";
if (d == Double.NEGATIVE_INFINITY) return "-Infinity";
if (d == 0.0) {
// Spec §21.1.3.2: zero exponent always renders as "+0"; -0 strips its sign.
if (digitsAbsent || digits == 0) return "0e+0";
StringBuilder sb = new StringBuilder(digits + 5);
sb.append("0.");
for (int i = 0; i < digits; i++) sb.append('0');
sb.append("e+0");
return sb.toString();
}
if (!digitsAbsent && (digits < 0 || digits > 100)) {
throw JsErrorException.rangeError("toExponential() fractionDigits must be between 0 and 100");
}
String formatted;
if (digitsAbsent) {
// Minimum-digits path: %.<n>e for the smallest n such that
// round-tripping recovers d. For the common test262 cases this is
// the same shape Double.toString produces, then we canonicalize.
formatted = String.format(java.util.Locale.ROOT, "%.15e", d);
// Trim trailing zeros from the mantissa fractional part.
int e = formatted.indexOf('e');
String mant = formatted.substring(0, e);
String exp = formatted.substring(e);
if (mant.contains(".")) {
mant = mant.replaceAll("0+$", "");
if (mant.endsWith(".")) mant = mant.substring(0, mant.length() - 1);
}
formatted = mant + exp;
} else {
formatted = String.format(java.util.Locale.ROOT, "%." + digits + "e", d);View on GitHub (pinned to a22eb90246)