parallax/jsPDF · error · Error

Invalid arguments passed to jsPDF.context2d.bezierCurveTo

Error message

Invalid arguments passed to jsPDF.context2d.bezierCurveTo

What it means

context2d.bezierCurveTo() adds a cubic Bezier curve using two control points (cp1x, cp1y, cp2x, cp2y) and one endpoint (x, y) — six parameters total. All six are validated with isNaN() because NaN values would corrupt the PDF cubic Bezier curve operator. This is the most parameter-heavy path command, making it the most likely to encounter NaN when a single coordinate in a data structure is missing.

Source

Thrown at src/modules/context2d.js:940

   * @param cp2y {Number} The y-coordinate of the second Bézier control point
   * @param x {Number} The x-coordinate of the ending point
   * @param y {Number} The y-coordinate of the ending point
   * @description The bezierCurveTo() method adds a point to the current path by using the specified control points that represent a cubic Bézier curve. <br /><br />A cubic bezier curve requires three points. The first two points are control points that are used in the cubic Bézier calculation and the last point is the ending point for the curve.  The starting point for the curve is the last point in the current path. If a path does not exist, use the beginPath() and moveTo() methods to define a starting point.
   */
  Context2D.prototype.bezierCurveTo = function(cp1x, cp1y, cp2x, cp2y, x, y) {
    if (
      isNaN(x) ||
      isNaN(y) ||
      isNaN(cp1x) ||
      isNaN(cp1y) ||
      isNaN(cp2x) ||
      isNaN(cp2y)
    ) {
      console.error(
        "jsPDF.context2d.bezierCurveTo: Invalid arguments",
        arguments
      );
      throw new Error(
        "Invalid arguments passed to jsPDF.context2d.bezierCurveTo"
      );
    }
    var pt0 = this.ctx.transform.applyToPoint(new Point(x, y));
    var pt1 = this.ctx.transform.applyToPoint(new Point(cp1x, cp1y));
    var pt2 = this.ctx.transform.applyToPoint(new Point(cp2x, cp2y));

    this.path.push({
      type: "bct",
      x1: pt1.x,
      y1: pt1.y,
      x2: pt2.x,
      y2: pt2.y,
      x: pt0.x,
      y: pt0.y
    });
    this.ctx.lastPoint = new Point(pt0.x, pt0.y);
  };

View on GitHub (pinned to a3930ce03a)

Solutions

  1. Validate all six parameters: if ([cp1x,cp1y,cp2x,cp2y,x,y].every(isFinite)) before calling
  2. Null-check control point objects before accessing their properties
  3. Use safe defaults for missing control points: fall back to endpoint coordinates
  4. Inspect the console.error output which logs all six arguments for diagnosis

Example fix

// before
ctx.bezierCurveTo(cp1.x, cp1.y, cp2?.x, cp2?.y, end.x, end.y);
// throws if cp2 is null (cp2?.x is undefined, isNaN(undefined) is true)

// after
var safeCp2 = cp2 || end; // default to endpoint
ctx.bezierCurveTo(cp1.x, cp1.y, safeCp2.x, safeCp2.y, end.x, end.y);
Defensive patterns

Strategy: validation

Validate before calling

// Validate all six parameters before calling bezierCurveTo
function safeBezierCurveTo(ctx, cp1x, cp1y, cp2x, cp2y, x, y) {
  var args = [cp1x, cp1y, cp2x, cp2y, x, y].map(Number);
  if (args.every(isFinite)) {
    ctx.bezierCurveTo(args[0], args[1], args[2], args[3], args[4], args[5]);
  } else {
    throw new TypeError('bezierCurveTo requires 6 finite numbers');
  }
}

Type guard

/**
 * @param {*} cp
 * @returns {boolean}
 */
function isValidControlPoint(cp) {
  return cp != null &&
    typeof cp.x === 'number' && isFinite(cp.x) &&
    typeof cp.y === 'number' && isFinite(cp.y);
}

Try / catch

try {
  ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
} catch (e) {
  if (e.message.includes('bezierCurveTo')) {
    // Null-safe defaults: use endpoint as control point fallback
    var safeCp2x = isFinite(cp2x) ? cp2x : x;
    var safeCp2y = isFinite(cp2y) ? cp2y : y;
    ctx.bezierCurveTo(cp1x || x, cp1y || y, safeCp2x, safeCp2y, x, y);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling ctx.bezierCurveTo(cp1x, cp1y, undefined, cp2y, x, y) where one of six values is undefined. Passing an object's properties where some are undefined: ctx.bezierCurveTo(cp1.x, cp1.y, cp2.x, cp2.y, end.x, end.y) where cp2 is null. Computing control points via matrix transforms that produce NaN for degenerate matrices.

Common situations: SVG path parsing for 'C'/'c' commands with malformed data. Font glyph rendering where bezier control points come from font metrics. Drawing splines from sparse data arrays. Coordinate transforms with singular (non-invertible) matrices. Object destructuring that yields undefined for missing keys.

Related errors


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