{"record":{"id":"03f6a43f0c37f0d4","repo":"parallax/jsPDF","slug":"invalid-arguments-passed-to-jspdf-context2d-bezier","errorCode":null,"errorMessage":"Invalid arguments passed to jsPDF.context2d.bezierCurveTo","messagePattern":"Invalid arguments passed to jsPDF\\.context2d\\.bezierCurveTo","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/modules/context2d.js","lineNumber":940,"sourceCode":"   * @param cp2y {Number} The y-coordinate of the second Bézier control point\n   * @param x {Number} The x-coordinate of the ending point\n   * @param y {Number} The y-coordinate of the ending point\n   * @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.\n   */\n  Context2D.prototype.bezierCurveTo = function(cp1x, cp1y, cp2x, cp2y, x, y) {\n    if (\n      isNaN(x) ||\n      isNaN(y) ||\n      isNaN(cp1x) ||\n      isNaN(cp1y) ||\n      isNaN(cp2x) ||\n      isNaN(cp2y)\n    ) {\n      console.error(\n        \"jsPDF.context2d.bezierCurveTo: Invalid arguments\",\n        arguments\n      );\n      throw new Error(\n        \"Invalid arguments passed to jsPDF.context2d.bezierCurveTo\"\n      );\n    }\n    var pt0 = this.ctx.transform.applyToPoint(new Point(x, y));\n    var pt1 = this.ctx.transform.applyToPoint(new Point(cp1x, cp1y));\n    var pt2 = this.ctx.transform.applyToPoint(new Point(cp2x, cp2y));\n\n    this.path.push({\n      type: \"bct\",\n      x1: pt1.x,\n      y1: pt1.y,\n      x2: pt2.x,\n      y2: pt2.y,\n      x: pt0.x,\n      y: pt0.y\n    });\n    this.ctx.lastPoint = new Point(pt0.x, pt0.y);\n  };","sourceCodeStart":922,"sourceCodeEnd":958,"githubUrl":"https://github.com/parallax/jsPDF/blob/a3930ce03a585a26b2c76d12a0f413ce96f6d1a3/src/modules/context2d.js#L922-L958","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Validate all six parameters: if ([cp1x,cp1y,cp2x,cp2y,x,y].every(isFinite)) before calling","Null-check control point objects before accessing their properties","Use safe defaults for missing control points: fall back to endpoint coordinates","Inspect the console.error output which logs all six arguments for diagnosis"],"exampleFix":"// before\nctx.bezierCurveTo(cp1.x, cp1.y, cp2?.x, cp2?.y, end.x, end.y);\n// throws if cp2 is null (cp2?.x is undefined, isNaN(undefined) is true)\n\n// after\nvar safeCp2 = cp2 || end; // default to endpoint\nctx.bezierCurveTo(cp1.x, cp1.y, safeCp2.x, safeCp2.y, end.x, end.y);","handlingStrategy":"validation","validationCode":"// Validate all six parameters before calling bezierCurveTo\nfunction safeBezierCurveTo(ctx, cp1x, cp1y, cp2x, cp2y, x, y) {\n  var args = [cp1x, cp1y, cp2x, cp2y, x, y].map(Number);\n  if (args.every(isFinite)) {\n    ctx.bezierCurveTo(args[0], args[1], args[2], args[3], args[4], args[5]);\n  } else {\n    throw new TypeError('bezierCurveTo requires 6 finite numbers');\n  }\n}","typeGuard":"/**\n * @param {*} cp\n * @returns {boolean}\n */\nfunction isValidControlPoint(cp) {\n  return cp != null &&\n    typeof cp.x === 'number' && isFinite(cp.x) &&\n    typeof cp.y === 'number' && isFinite(cp.y);\n}","tryCatchPattern":"try {\n  ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);\n} catch (e) {\n  if (e.message.includes('bezierCurveTo')) {\n    // Null-safe defaults: use endpoint as control point fallback\n    var safeCp2x = isFinite(cp2x) ? cp2x : x;\n    var safeCp2y = isFinite(cp2y) ? cp2y : y;\n    ctx.bezierCurveTo(cp1x || x, cp1y || y, safeCp2x, safeCp2y, x, y);\n  } else throw e;\n}","preventionTips":["Null-check control point objects before destructuring their properties","Validate all six parameters with isFinite before calling bezierCurveTo","Use endpoint coordinates as safe fallback for missing control points"],"tags":["context2d","path","bezier","nan","coordinates","validation"],"backgroundTag":null,"analyzedSha":"a3930ce03a585a26b2c76d12a0f413ce96f6d1a3","analyzedAt":"2026-08-13T05:33:39.648Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}