{"record":{"id":"37d236f02da38f62","repo":"parallax/jsPDF","slug":"invalid-argument-passed-to-jspdf-f3","errorCode":null,"errorMessage":"Invalid argument passed to jsPDF.f3","messagePattern":"Invalid argument passed to jsPDF\\.f3","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/jspdf.js","lineNumber":536,"sourceCode":"    };\n  } else {\n    hpf = API.hpf = API.__private__.hpf = function(number) {\n      if (isNaN(number)) {\n        throw new Error(\"Invalid argument passed to jsPDF.hpf\");\n      }\n      return roundToPrecision(number, 16);\n    };\n  }\n  var f2 = (API.f2 = API.__private__.f2 = function(number) {\n    if (isNaN(number)) {\n      throw new Error(\"Invalid argument passed to jsPDF.f2\");\n    }\n    return roundToPrecision(number, 2);\n  });\n\n  var f3 = (API.__private__.f3 = function(number) {\n    if (isNaN(number)) {\n      throw new Error(\"Invalid argument passed to jsPDF.f3\");\n    }\n    return roundToPrecision(number, 3);\n  });\n\n  var scale = (API.scale = API.__private__.scale = function(number) {\n    if (isNaN(number)) {\n      throw new Error(\"Invalid argument passed to jsPDF.scale\");\n    }\n    if (apiMode === ApiMode.COMPAT) {\n      return number * scaleFactor;\n    } else if (apiMode === ApiMode.ADVANCED) {\n      return number;\n    }\n  });\n\n  var transformY = function(y) {\n    if (apiMode === ApiMode.COMPAT) {\n      return getPageHeight() - y;","sourceCodeStart":518,"sourceCodeEnd":554,"githubUrl":"https://github.com/parallax/jsPDF/blob/a3930ce03a585a26b2c76d12a0f413ce96f6d1a3/src/jspdf.js#L518-L554","documentation":"`f3` (src/jspdf.js:534) formats to 3 decimal places via `roundToPrecision(number, 3)` and throws at src/jspdf.js:536 for NaN. Like f2 it is an internal formatter used by encodeColorString (precision 3 default for grayscale/RGB) and various geometry outputs. The root cause is always a NaN reaching a 3-decimal formatting path.","triggerScenarios":"A NaN color channel flowing into encodeColorString's default (precision 3) branch; a NaN in a coordinate that is formatted at 3-decimal precision; passing undefined into a numeric position argument.","commonSituations":"Same family as f2: unvalidated numeric data from user input, DOM measurements, or deserialized JSON producing NaN; color values from a picker that occasionally emits null.","solutions":["Trace the NaN to the offending argument in the failing call.","Coerce all numeric inputs with `Number.isFinite(v) ? v : 0`.","For colors, pass hex strings or validated numbers in [0,255] (or [0,1]).","Centralize numeric sanitization at the boundary of your rendering layer."],"exampleFix":"// before\n doc.setTextColor(ch.r, ch.g, ch.b);  // ch.b is NaN\n\n// after\n var b = Number.isFinite(ch.b) ? ch.b : 0;\n doc.setTextColor(ch.r, ch.g, b);","handlingStrategy":"validation","validationCode":"function finiteNum(x) { return Number.isFinite(x) ? x : 0; }\ndoc.setTextColor(finiteNum(r), finiteNum(g), finiteNum(b));","typeGuard":"function isFiniteNumber(x) { return typeof x === 'number' && Number.isFinite(x); }","tryCatchPattern":"try {\n  doc.setTextColor(r, g, b);\n} catch (e) {\n  if (/jsPDF\\.f3/.test(e.message)) {\n    doc.setTextColor(finiteNum(r), finiteNum(g), finiteNum(b));\n  } else throw e;\n}","preventionTips":["Validate numeric color/coordinate channels before text and draw calls.","Default missing channels to 0 rather than passing undefined/NaN.","Use hex strings for colors when channel provenance is uncertain."],"tags":["numeric","f3","nan","formatting","color","geometry"],"backgroundTag":null,"analyzedSha":"a3930ce03a585a26b2c76d12a0f413ce96f6d1a3","analyzedAt":"2026-08-13T05:33:39.648Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}