Stirling-Tools/Stirling-PDF · critical · Error

PDFium: failed to create new document

Error message

PDFium: failed to create new document

What it means

`createEmptyDocument` calls `FPDF_CreateNewDocument()` to mint a blank PDF, then immediately saves it via `PDFiumExt_SaveAsCopy`. A null doc pointer means PDFium couldn't allocate — same heap-exhaustion/ corrupted-module root cause as errors 28/29/30, just on the empty-document factory path.

Source

Thrown at frontend/editor/src/core/services/pdfiumService.ts:1113

      });

      m.FPDFPage_CloseAnnot(annotPtr);
    }

    m.FPDF_ClosePage(pagePtr);
    return { links, pageWidth, pageHeight };
  } finally {
    closeDocAndFreeBuffer(m, docPtr);
  }
}

/**
 * Create a new empty PDF document, returning its raw data.
 */
export async function createEmptyDocument(): Promise<ArrayBuffer> {
  const m = await getPdfiumModule();
  const docPtr = m.FPDF_CreateNewDocument();
  if (!docPtr) throw new Error("PDFium: failed to create new document");
  const writerPtr = m.PDFiumExt_OpenFileWriter();
  m.PDFiumExt_SaveAsCopy(docPtr, writerPtr);
  const size = m.PDFiumExt_GetFileWriterSize(writerPtr);
  const outBuf = m.pdfium.wasmExports.malloc(size);
  m.PDFiumExt_GetFileWriterData(writerPtr, outBuf, size);
  const result = new ArrayBuffer(size);
  const view = new Uint8Array(result);
  for (let i = 0; i < size; i++) {
    view[i] = m.pdfium.getValue(outBuf + i, "i8") & 0xff;
  }
  m.pdfium.wasmExports.free(outBuf);
  m.PDFiumExt_CloseFileWriter(writerPtr);
  closeDocAndFreeBuffer(m, docPtr);
  return result;
}

/**
 * Save a raw document pointer to an ArrayBuffer.

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Retry once after `resetPdfiumModule()`.
  2. Ensure `PDFiumExt_Init` succeeded (its failure is silently swallowed in `initPdfiumModule`) before relying on the extension save APIs.
  3. Close all open documents before minting a new empty one.
  4. Track and bound the number of live PDFium documents.

Example fix

// before
const docPtr = m.FPDF_CreateNewDocument();
if (!docPtr) throw new Error("PDFium: failed to create new document");

// after
let docPtr = m.FPDF_CreateNewDocument();
if (!docPtr) {
  resetPdfiumModule();
  const m2 = await getPdfiumModule();
  docPtr = m2.FPDF_CreateNewDocument();
}
if (!docPtr) throw new Error("PDFium: failed to create new document");
Defensive patterns

Strategy: retry

Validate before calling

// Confirm extensions are present before relying on createEmptyDocument + save
const m = await getPdfiumModule();
if (typeof m.PDFiumExt_SaveAsCopy !== "function") {
  throw new Error("PDFium save extensions unavailable");
}

Try / catch

async function emptyDocWithRetry(): Promise<ArrayBuffer> {
  try { return await createEmptyDocument(); }
  catch (e) {
    if (e instanceof Error && e.message.includes("failed to create new document")) {
      resetPdfiumModule();
      return await createEmptyDocument();
    }
    throw e;
  }
}

Prevention

When it happens

Trigger: Creating an empty PDF after heavy prior PDFium usage filled the WASM heap; the module is in a bad state after an unhandled pointer error; `PDFiumExt_Init` failed during init (swallowed) leaving extensions unavailable.

Common situations: Starting a new document in a long session; Safari WASM ceiling; a leak accumulating document handles.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/4729c05eefbad924. Report an issue: GitHub.