{"record":{"id":"e6d514cb96f96a5a","repo":"Stirling-Tools/Stirling-PDF","slug":"invalid-pdf-distance-must-be-positive","errorCode":null,"errorMessage":"Invalid PDF distance (must be positive)","messagePattern":"Invalid PDF distance \\(must be positive\\)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/editor/src/core/utils/measurementUtils.ts","lineNumber":363,"sourceCode":"  }\n\n  const baseFactor = getUnitFactor(unit);\n  if (!baseFactor) {\n    return null;\n  }\n\n  // ratio = factor / baseFactor\n  const ratio = factor / baseFactor;\n  return Number.isFinite(ratio) && ratio > 0 ? ratio : null;\n}\n\nexport function calculateCalibratedScale(\n  pdfDistancePts: number,\n  realDistance: number,\n  unit: string,\n): MeasureScale {\n  if (!Number.isFinite(pdfDistancePts) || pdfDistancePts <= 0) {\n    throw new Error(\"Invalid PDF distance (must be positive)\");\n  }\n\n  if (!Number.isFinite(realDistance) || realDistance <= 0) {\n    throw new Error(\"Invalid real-world distance (must be positive)\");\n  }\n\n  const baseFactor = getUnitFactor(unit);\n  if (!baseFactor) {\n    throw new Error(`Unsupported unit: ${unit}`);\n  }\n\n  const factor = realDistance / pdfDistancePts;\n  const ratio = deriveRatioFromFactor(factor, unit);\n\n  return {\n    factor,\n    ratio,\n    unit,","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/core/utils/measurementUtils.ts#L345-L381","documentation":"Thrown by calculateCalibratedScale when pdfDistancePts fails Number.isFinite or is <= 0. pdfDistancePts is the distance between two calibration points measured in PDF points (1/72 inch) and is divided into realDistance to derive the scale factor, so it must be a positive finite number.","triggerScenarios":"Two calibration clicks land on the same coordinate (distance 0); the measurement tool computes distance from an uninitialized/deleted PagePoint (NaN); a corrupt or zero-size page geometry yields 0; Infinity from a broken coordinate transform.","commonSituations":"User clicks without dragging during calibration; page viewport math returns NaN for a rotated/scaled page; race condition where calibration fires before the page geometry is loaded.","solutions":["Reject calibration when the two points are within an epsilon (e.g. < 1pt) and prompt the user to drag further.","Validate PagePoint coordinates are finite numbers before computing distance.","Ensure page geometry (width/height/rotation/scale) is loaded before enabling the calibration gesture.","Wrap calculateCalibratedScale in try/catch at the UI layer and show an actionable message."],"exampleFix":"// before\nconst scale = calculateCalibratedScale(pdfDistancePts, realDistance, unit);\n\n// after\nif (pdfDistancePts < 1) {\n  throw new Error(\"Click and drag across the feature you want to measure; the measured distance is too small.\");\n}\nconst scale = calculateCalibratedScale(pdfDistancePts, realDistance, unit);","handlingStrategy":"validation","validationCode":"if (!Number.isFinite(pdfDistancePts) || pdfDistancePts < 1) {\n  throw new Error(\"Calibration failed: drag across a larger feature (measured distance too small).\");\n}\nconst scale = calculateCalibratedScale(pdfDistancePts, realDistance, unit);","typeGuard":"const isValidPdfDistance = (d: unknown): d is number =>\n  typeof d === \"number\" && Number.isFinite(d) && d > 0;","tryCatchPattern":null,"preventionTips":["Reject calibration when the two points are within an epsilon (< 1pt).","Confirm PagePoint coordinates are finite before computing distance.","Ensure page geometry is loaded before enabling the calibration gesture."],"tags":["validation","measurement","calibration","math"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}