Stirling-Tools/Stirling-PDF · error · Error
Failed to create link annotation
Error message
Failed to create link annotation
What it means
Thrown in createLinkAnnotation when m.FPDFPage_CreateAnnot(pagePtr, FPDF_ANNOT_LINK) returns a falsy pointer. By this point the page loaded successfully, so a null annotation pointer indicates PDFium ran out of WASM memory, the page object is internally inconsistent, or the annotation subsystem could not allocate. This is rare and usually points to resource exhaustion or a corrupt page.
Source
Thrown at frontend/editor/src/core/utils/pdfLinkUtils.ts:129
const pageCount = m.FPDF_GetPageCount(docPtr);
if (
destinationPage !== undefined &&
(destinationPage < 0 || destinationPage >= pageCount)
) {
throw new RangeError(
`createLinkAnnotation: destinationPage ${destinationPage} out of range [0, ${pageCount})`,
);
}
const pagePtr = m.FPDF_LoadPage(docPtr, pageIndex);
if (!pagePtr) throw new Error(`Failed to load page ${pageIndex}`);
try {
const pageHeight = m.FPDF_GetPageHeightF(pagePtr);
const annotPtr = m.FPDFPage_CreateAnnot(pagePtr, FPDF_ANNOT_LINK);
if (!annotPtr) {
throw new Error("Failed to create link annotation");
}
try {
// Set rect (convert from CSS top-left to PDF bottom-left origin)
// FS_RECTF layout: { left, top, right, bottom } where top > bottom in PDF coords
const pdfLeft = rect.x;
const pdfTop = pageHeight - rect.y; // CSS y=0 → PDF top
const pdfRight = rect.x + rect.width;
const pdfBottom = pageHeight - rect.y - rect.height; // CSS bottom → PDF bottom
const rectBuf = m.pdfium.wasmExports.malloc(4 * 4);
m.pdfium.setValue(rectBuf, pdfLeft, "float"); // offset 0: left
m.pdfium.setValue(rectBuf + 4, pdfTop, "float"); // offset 4: top (larger y)
m.pdfium.setValue(rectBuf + 8, pdfRight, "float"); // offset 8: right
m.pdfium.setValue(rectBuf + 12, pdfBottom, "float"); // offset 12: bottom (smaller y)
m.FPDFAnnot_SetRect(annotPtr, rectBuf);
m.pdfium.wasmExports.free(rectBuf);
View on GitHub (pinned to 9ef20dcab8)
Solutions
- Ensure the WASM module has sufficient heap (avoid large simultaneous buffers; free with closeDocAndFreeBuffer promptly).
- Rate-limit bulk annotation creation and verify each annotation pointer before continuing.
- On failure, abort the transaction rather than continuing with a partial set of annotations.
- Re-open the document and retry once; if it persists, report the page as uneditable.
Example fix
// before
const annotPtr = m.FPDFPage_CreateAnnot(pagePtr, FPDF_ANNOT_LINK);
if (!annotPtr) throw new Error("Failed to create link annotation");
// after
const annotPtr = m.FPDFPage_CreateAnnot(pagePtr, FPDF_ANNOT_LINK);
if (!annotPtr) {
throw new Error(
"Failed to create link annotation: PDFium could not allocate the annotation (possible WASM memory exhaustion or corrupt page).",
);
} Defensive patterns
Strategy: retry
Validate before calling
// No pure pre-check exists for PDFium annotation allocation; budget the heap instead. // Ensure prior buffers are freed and keep a single open document at a time.
Prevention
- Free WASM buffers (closeDocAndFreeBuffer) promptly between operations.
- Rate-limit bulk annotation creation and verify each annotation pointer.
- Abort the transaction on first failure rather than producing a partial set.
When it happens
Trigger: Creating many annotations in a loop until WASM heap is exhausted; a malformed page object that loads but rejects annotation creation; concurrent annotation operations on the same module without synchronization.
Common situations: Bulk link-annotation workflows on large PDFs; low-memory devices; PDFs with broken annotation dictionaries already present.
Related errors
- PDFium: failed to create document
- PDFium: failed to create destination document
- PDFium: failed to create document
- PDFium: failed to create new document
- PDFium: failed to create document
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/225c76f4fe8d32bf.
Report an issue: GitHub.