karatelabs/karate · error · RangeError

toFixed() digits argument must be between 0 and 100

Error message

toFixed() digits argument must be between 0 and 100

What it means

toFixed() was called with a digits argument outside the allowed 0-100 range. Per ECMAScript §21.1.3.3 the fraction-digit count must be an integer between 0 and 100 inclusive; the engine mirrors the spec RangeError text.

Solutions

  1. Clamp the digits argument: Math.min(100, Math.max(0, digits)).
  2. Check the source of the precision value for off-by-one or sign errors.
  3. Use Math.round/truncation manually if you intentionally need more than 100 digits.

Example fix

// before
value.toFixed(digits)
// after
value.toFixed(Math.min(100, Math.max(0, digits)))
Defensive patterns

Strategy: validation

Validate before calling

if (!Number.isInteger(digits) || digits < 0 || digits > 100) throw new Error('digits must be 0-100');

Try / catch

try { return value.toFixed(digits); } catch (e) { if (String(e).includes('toFixed() digits')) return value.toFixed(2); throw e; }

Prevention

When it happens

Trigger: Number.prototype.toFixed(n) where n < 0 or n > 100, e.g. (1.5).toFixed(-1) or (1.5).toFixed(101).

Common situations: Computing precision from a variable or config that went negative or unbounded; a typo like toFixed(1000); user-supplied precision values not clamped before use.

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


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

Appendix: source

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

    /**
     * Spec §21.3.2.28: NaN/±Inf/±0/integer unchanged; (0, 0.5) -&gt; +0; [-0.5, 0) -&gt; -0;
     * otherwise floor(x + 0.5). Note this is "round half toward +Infinity", NOT "round half away
     * from zero": Math.round(-1.5) === -1, NOT -2. The integer short-circuit is load-bearing near
     * MAX_SAFE_INTEGER (ulp &ge; 1), where x + 0.5 rounds to a different integer than x.
     */
    public static double round(double x) {
        if (Double.isNaN(x) || Double.isInfinite(x) || x == 0) return x;
        if (x == Math.floor(x)) return x;
        if (x > 0 && x < 0.5) return 0.0;
        if (x < 0 && x >= -0.5) return -0.0;
        return Math.floor(x + 0.5);
    }

    /** Spec §21.1.3.3, with the same RangeError text the installed method throws. */
    public static String toFixed(double value, int digits) {
        if (digits < 0 || digits > 100) {
            throw JsErrorException.rangeError("toFixed() digits argument must be between 0 and 100");
        }
        if (Double.isNaN(value)) return "NaN";
        if (value == Double.POSITIVE_INFINITY) return "Infinity";
        if (value == Double.NEGATIVE_INFINITY) return "-Infinity";
        // Spec: |x| ≥ 10^21 falls back to ToString(x); BigDecimal of such doubles
        // produces a noisy decimal expansion (e.g. 1e21 -> "1000000000000000040000")
        // that doesn't match JS's "1e+21" canonical form.
        if (Math.abs(value) >= 1e21) {
            return Terms.numberToString(value);
        }
        BigDecimal bd = BigDecimal.valueOf(value);
        bd = bd.setScale(digits, RoundingMode.HALF_UP);
        StringBuilder pattern = new StringBuilder("0");
        if (digits > 0) {
            pattern.append(".");
            pattern.append("0".repeat(digits));
        }
        DecimalFormat df = new DecimalFormat(pattern.toString());

View on GitHub (pinned to a22eb90246)