Stirling-Tools/Stirling-PDF · critical · Error

PDFium: failed to create document

Error message

PDFium: failed to create document

What it means

`PdfiumDocument.create()` (the drop-in replacement for pdf-lib's `PDFDocument.create()`) calls `FPDF_CreateNewDocument()` and throws on a null pointer. An empty document failing to allocate points to WASM heap exhaustion or a corrupted/uninitialised module — `create()` is called early in builder flows, so if this fails, every subsequent builder operation would too.

Source

Thrown at frontend/editor/src/core/services/pdfiumDocBuilder.ts:350

// Document abstraction
// ---------------------------------------------------------------------------

export class PdfiumDocument {
  readonly _m: WrappedPdfiumModule;
  readonly _docPtr: number;
  private _pages: PdfiumPage[] = [];
  private _fonts: Map<string, PdfiumFont> = new Map();

  private constructor(m: WrappedPdfiumModule, docPtr: number) {
    this._m = m;
    this._docPtr = docPtr;
  }

  /** Create a new empty PDF document. Drop-in replacement for `PDFDocument.create()`. */
  static async create(): Promise<PdfiumDocument> {
    const m = await getPdfiumModule();
    const docPtr = m.FPDF_CreateNewDocument();
    if (!docPtr) throw new Error("PDFium: failed to create document");
    return new PdfiumDocument(m, docPtr);
  }

  /** Add a new page to the document. */
  addPage(dimensions: [number, number]): PdfiumPage {
    const [width, height] = dimensions;
    const insertIdx = this._pages.length;
    const pagePtr = this._m.FPDFPage_New(
      this._docPtr,
      insertIdx,
      width,
      height,
    );
    if (!pagePtr) throw new Error("PDFium: failed to create page");
    const page = new PdfiumPage(this._m, this._docPtr, pagePtr, width, height);
    this._pages.push(page);
    return page;
  }

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Retry `PdfiumDocument.create()` once after `resetPdfiumModule()`.
  2. Audit the doc-builder usage path for unclosed `PdfiumDocument` instances (ensure `dispose()`/close is always called).
  3. Confirm `getPdfiumModule()` resolved fully (PDFiumExt_Init succeeded) before heavy builder work.
  4. Reduce simultaneous live documents.

Example fix

// before
static async create(): Promise<PdfiumDocument> {
  const m = await getPdfiumModule();
  const docPtr = m.FPDF_CreateNewDocument();
  if (!docPtr) throw new Error("PDFium: failed to create document");
  return new PdfiumDocument(m, docPtr);
}

// after
static async create(): Promise<PdfiumDocument> {
  let m = await getPdfiumModule();
  let docPtr = m.FPDF_CreateNewDocument();
  if (!docPtr) {
    resetPdfiumModule();
    m = await getPdfiumModule();
    docPtr = m.FPDF_CreateNewDocument();
  }
  if (!docPtr) throw new Error("PDFium: failed to create document");
  return new PdfiumDocument(m, docPtr);
}
Defensive patterns

Strategy: retry

Validate before calling

// Ensure the module fully initialised (PDFiumExt_Init not swallowed) before builder work
const m = await getPdfiumModule();
if (typeof m.PDFiumExt_OpenFileWriter !== "function") {
  console.warn("PDFium extensions unavailable; builder may fail.");
}

Try / catch

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

Prevention

When it happens

Trigger: Calling `PdfiumDocument.create()` after heavy prior PDFium use filled the WASM heap; the module's `PDFiumExt_Init` failed during `initPdfiumModule` (caught and swallowed, leaving extensions unset); a prior unhandled pointer error left PDFium in a bad state.

Common situations: Building a new PDF (e.g. assembling a multi-file document via the doc builder) in a long session; Safari's lower WASM ceiling; a bug that leaked document handles over time.

Related errors


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