{"record":{"id":"6938b18c84d88965","repo":"Stirling-Tools/Stirling-PDF","slug":"failed-to-load-page-pageindex","errorCode":null,"errorMessage":"Failed to load page ${pageIndex}","messagePattern":"Failed to load page (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/editor/src/core/utils/pdfLinkUtils.ts","lineNumber":122,"sourceCode":"    throw new Error(\"createLinkAnnotation: rect dimensions must be positive\");\n  }\n\n  const m = await getPdfiumModule();\n  const docPtr = await openRawDocumentSafe(data, password);\n\n  try {\n    const pageCount = m.FPDF_GetPageCount(docPtr);\n    if (\n      destinationPage !== undefined &&\n      (destinationPage < 0 || destinationPage >= pageCount)\n    ) {\n      throw new RangeError(\n        `createLinkAnnotation: destinationPage ${destinationPage} out of range [0, ${pageCount})`,\n      );\n    }\n\n    const pagePtr = m.FPDF_LoadPage(docPtr, pageIndex);\n    if (!pagePtr) throw new Error(`Failed to load page ${pageIndex}`);\n\n    try {\n      const pageHeight = m.FPDF_GetPageHeightF(pagePtr);\n\n      const annotPtr = m.FPDFPage_CreateAnnot(pagePtr, FPDF_ANNOT_LINK);\n      if (!annotPtr) {\n        throw new Error(\"Failed to create link annotation\");\n      }\n\n      try {\n        // Set rect (convert from CSS top-left to PDF bottom-left origin)\n        // FS_RECTF layout: { left, top, right, bottom } where top > bottom in PDF coords\n        const pdfLeft = rect.x;\n        const pdfTop = pageHeight - rect.y; // CSS y=0 → PDF top\n        const pdfRight = rect.x + rect.width;\n        const pdfBottom = pageHeight - rect.y - rect.height; // CSS bottom → PDF bottom\n\n        const rectBuf = m.pdfium.wasmExports.malloc(4 * 4);","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/core/utils/pdfLinkUtils.ts#L104-L140","documentation":"Thrown in createLinkAnnotation when m.FPDF_LoadPage(docPtr, pageIndex) returns a falsy (0/null) pointer. PDFium returns null when pageIndex is out of range or when the document/page is corrupt. Note the function bounds-checks destinationPage but does NOT bounds-check pageIndex against FPDF_GetPageCount before this call, so an out-of-range pageIndex reaches FPDF_LoadPage directly.","triggerScenarios":"Passing a pageIndex >= pageCount or < 0 (no guard unlike destinationPage); operating on a PDF whose page table is corrupt; calling before the document finished parsing (pagePtr null due to a parse error swallowed upstream).","commonSituations":"Index computed from a stale page list (the user deleted/reordered pages); zero-based vs one-based index confusion; PDF produced by a faulty generator with a broken page tree.","solutions":["Bounds-check pageIndex against FPDF_GetPageCount(docPtr) before FPDF_LoadPage, mirroring the existing destinationPage guard.","Refresh the page count from the document right before annotation creation rather than caching it.","Validate pageIndex is a non-negative integer at the API boundary.","Wrap createLinkAnnotation at the caller and surface a page-specific error to the user."],"exampleFix":"// before\nconst pagePtr = m.FPDF_LoadPage(docPtr, pageIndex);\nif (!pagePtr) throw new Error(`Failed to load page ${pageIndex}`);\n\n// after\nconst pageCount = m.FPDF_GetPageCount(docPtr);\nif (pageIndex < 0 || pageIndex >= pageCount) {\n  throw new RangeError(`pageIndex ${pageIndex} out of range [0, ${pageCount})`);\n}\nconst pagePtr = m.FPDF_LoadPage(docPtr, pageIndex);\nif (!pagePtr) throw new Error(`Failed to load page ${pageIndex} (corrupt page?)`);","handlingStrategy":"validation","validationCode":"const pageCount = m.FPDF_GetPageCount(docPtr);\nif (!Number.isInteger(pageIndex) || pageIndex < 0 || pageIndex >= pageCount) {\n  throw new RangeError(`pageIndex ${pageIndex} out of range [0, ${pageCount})`);\n}","typeGuard":"const isPageIndex = (i: number, pageCount: number): i is number =>\n  Number.isInteger(i) && i >= 0 && i < pageCount;","tryCatchPattern":"try {\n  await createLinkAnnotation(data, pageIndex, rect, options);\n} catch (error) {\n  if (/Failed to load page/.test((error as Error).message)) {\n    // refresh page list and retry / notify user the page no longer exists\n  }\n  throw error;\n}","preventionTips":["Always bounds-check pageIndex against FPDF_GetPageCount before FPDF_LoadPage.","Refresh the page count from the document right before annotation creation.","Validate pageIndex is a non-negative integer at the API boundary."],"tags":["pdfium","wasm","validation","annotation","indexing"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}