{"record":{"id":"ab49e9a7f23f4836","repo":"Stirling-Tools/Stirling-PDF","slug":"pdfium-failed-to-create-document","errorCode":null,"errorMessage":"PDFium: failed to create document","messagePattern":"PDFium: failed to create document","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/editor/src/core/hooks/tools/adjustContrast/useAdjustContrastOperation.ts","lineNumber":45,"sourceCode":"  canvas.height = viewport.height;\n  const ctx = canvas.getContext(\"2d\");\n  if (!ctx) throw new Error(\"Canvas 2D context unavailable\");\n  await page.render({ canvasContext: ctx, canvas, viewport }).promise;\n  return canvas;\n}\n\n// Render, adjust, and assemble all pages of a single PDF into a new PDF using PDFium\nasync function buildAdjustedPdfForFile(\n  file: File,\n  params: AdjustContrastParameters,\n): Promise<File> {\n  const m = await getPdfiumModule();\n  const arrayBuffer = await file.arrayBuffer();\n  const pdf = await pdfWorkerManager.createDocument(arrayBuffer, {});\n  const pageCount = pdf.numPages;\n\n  const docPtr = m.FPDF_CreateNewDocument();\n  if (!docPtr) throw new Error(\"PDFium: failed to create document\");\n\n  try {\n    for (let p = 1; p <= pageCount; p++) {\n      const srcCanvas = await renderPdfPageToCanvas(pdf, p, 2);\n      const adjusted = applyAdjustmentsToCanvas(srcCanvas, params);\n      const ctx = adjusted.getContext(\"2d\");\n      if (!ctx) {\n        console.warn(\n          `[adjustContrast] Skipping page ${p}: failed to get canvas context`,\n        );\n        continue;\n      }\n\n      const imageData = ctx.getImageData(0, 0, adjusted.width, adjusted.height);\n      const imgWidth = imageData.width;\n      const imgHeight = imageData.height;\n\n      // Since we render at scale 2, the actual PDF page size is half","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/core/hooks/tools/adjustContrast/useAdjustContrastOperation.ts#L27-L63","documentation":"Thrown when the PDFium WASM export `FPDF_CreateNewDocument()` returns a null/zero pointer. PDFium returns null on allocation failure inside the WASM heap — i.e. the module has exhausted its linear memory. The pointer is the root for every assembled page, so processing cannot continue.","triggerScenarios":"The adjust-contrast pipeline already decoded the source PDF and rendered pages to canvases at scale 2; for a large PDF the WASM heap is near its limit when a fresh output document is allocated. Also possible if the PDFium module failed to fully initialize (memory grew past the configured maximum).","commonSituations":"Adjusting contrast on a 100+ page or very high-resolution PDF; running in a tab where other PDFium-using tools already consumed WASM memory; browser memory limits lower than the document demands.","solutions":["Stream pages — create, fill, save, and close the output document in batches rather than holding the full docPtr open for every page.","Increase the PDFium WASM initial/maximum memory in the module loader config (e.g. allow memory growth).","Lower the render scale (the main memory driver) so each page bitmap is smaller.","Free per-page bitmaps and image objects promptly (already partly done) and verify no leaks across iterations."],"exampleFix":"// before\nconst docPtr = m.FPDF_CreateNewDocument();\nif (!docPtr) throw new Error(\"PDFium: failed to create document\");\n\n// after — surface size context and bail with a recoverable message\nconst docPtr = m.FPDF_CreateNewDocument();\nif (!docPtr) {\n  throw new Error(`PDFium: failed to create document (pages=${pageCount}, wasm heap likely exhausted)`);\n}","handlingStrategy":"validation","validationCode":"// Check WASM memory headroom before allocating the output document\nconst mem = m.pdfium.wasmExports as unknown as { memory?: { buffer: ArrayBuffer } };\nconst remaining = mem.memory ? mem.memory.buffer.byteLength : Infinity;\nif (pageCount > 200) {\n  // consider batching or lowering scale before calling FPDF_CreateNewDocument\n}","typeGuard":"function isDocPtr(p: number): p is number { return typeof p === \"number\" && p !== 0; }","tryCatchPattern":"try {\n  return await buildAdjustedPdfForFile(file, params);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith(\"PDFium: failed to create document\")) {\n    // retry once at scale 1, then surface a 'document too large' message\n  }\n  throw e;\n}","preventionTips":["Stream/batch the output document instead of holding one open for every page.","Lower render scale to reduce per-page bitmap memory.","Verify the PDFium module loader allows heap growth for large documents."],"tags":["pdfium","wasm","memory","adjust-contrast"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}