parallax/jsPDF · error · Error

Invalid argument passed to jsPDF.roundToPrecision

Error message

Invalid argument passed to jsPDF.roundToPrecision

What it means

`roundToPrecision` (src/jspdf.js:488) is the low-level number formatter that backs `hpf`, `f2`, and `f3`. It throws at src/jspdf.js:493 when either the value or the resolved precision is NaN. Precision resolves to `precision || parmPrecision`, so it can be NaN if the constructor's `options.precision` was set to a non-numeric value. End users usually hit this indirectly — a NaN value (e.g. from a division by zero or a failed parseFloat) propagates into a drawing call that ultimately formats coordinates through roundToPrecision.

Source

Thrown at src/jspdf.js:494

  };

  var advancedApiModeTrap = function(methodName) {
    if (apiMode !== ApiMode.ADVANCED) {
      throw new Error(
        methodName +
          " is only available in 'advanced' API mode. " +
          "You need to call advancedAPI() first."
      );
    }
  };

  var roundToPrecision = (API.roundToPrecision = API.__private__.roundToPrecision = function(
    number,
    parmPrecision
  ) {
    var tmpPrecision = precision || parmPrecision;
    if (isNaN(number) || isNaN(tmpPrecision)) {
      throw new Error("Invalid argument passed to jsPDF.roundToPrecision");
    }
    return number.toFixed(tmpPrecision).replace(/0+$/, "");
  });

  // high precision float
  var hpf;
  if (typeof floatPrecision === "number") {
    hpf = API.hpf = API.__private__.hpf = function(number) {
      if (isNaN(number)) {
        throw new Error("Invalid argument passed to jsPDF.hpf");
      }
      return roundToPrecision(number, floatPrecision);
    };
  } else if (floatPrecision === "smart") {
    hpf = API.hpf = API.__private__.hpf = function(number) {
      if (isNaN(number)) {
        throw new Error("Invalid argument passed to jsPDF.hpf");
      }

View on GitHub (pinned to a3930ce03a)

Solutions

  1. Trace the NaN to its source: log the value just before the failing API call and walk back to where it was computed.
  2. Sanitize numeric inputs with a helper that coerces and defaults: `Number.isFinite(x) ? x : 0`.
  3. If setting `options.precision`, pass a finite positive integer (e.g. 3).
  4. For dynamically computed geometry, guard each step (division, sqrt, parseFloat) and fall back to a sane default.

Example fix

// before
 doc.line(NaN, 0, x, y);   // NaN flows into roundToPrecision

// after
 var safeX = Number.isFinite(x) ? x : 0;
 doc.line(safeX, 0, x, y);
Defensive patterns

Strategy: validation

Validate before calling

function finiteNum(x, dflt) { return Number.isFinite(x) ? x : (dflt || 0); }
// and ensure precision is a finite number when constructing:
var precision = Number.isFinite(opts.precision) ? opts.precision : undefined;
new jsPDF(Object.assign({}, opts, { precision: precision }));

Type guard

function isFiniteNumber(x) { return typeof x === 'number' && Number.isFinite(x); }

Try / catch

try {
  doc.line(finiteNum(x), y, x2, y2);
} catch (e) {
  if (/roundToPrecision/.test(e.message)) {
    console.warn('Skipping non-finite value in line()');
  } else throw e;
}

Prevention

When it happens

Trigger: Passing `options.precision: NaN` (or a non-numeric string coerced to NaN) to the jsPDF constructor; feeding NaN/undefined into any geometry method whose value is later formatted; a computed coordinate that became NaN through `0/0`, `Math.sqrt(-1)`, or `parseFloat(undefined)`.

Common situations: Layout code that computes positions from dynamic data where a divisor is zero; reading a missing numeric attribute from user data and passing `parseFloat(undefined)`; setting precision from a config value that is a string like `'high'` instead of a number.

Related errors


AI-assisted analysis of parallax/jsPDF@a3930ce03a (2026-08-13). Data as JSON: /api/errors/a5f9ec3f403555de. Report an issue: GitHub.