Stirling-Tools/Stirling-PDF · error · Error
PDFium: failed to create page
Error message
PDFium: failed to create page
What it means
`PdfiumDocument.addPage(dimensions)` calls `FPDFPage_New(docPtr, index, width, height)`. A null return means page creation failed. Unlike document creation, page creation has a concrete precondition: `width`/`height` must be positive finite numbers within PDFium's coordinate range. Zero, negative, NaN, Infinity, or astronomically large values make PDFium refuse the page.
Source
Thrown at frontend/editor/src/core/services/pdfiumDocBuilder.ts:364
/** 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;
}
/** Embed a standard PDF font. Returns a PdfiumFont for text measurement and drawing. */
async embedFont(fontName: string): Promise<PdfiumFont> {
if (this._fonts.has(fontName)) return this._fonts.get(fontName)!;
const font = new PdfiumFont(fontName);
this._fonts.set(fontName, font);
return font;
}
/** Embed a PNG image from raw bytes. */
async embedPng(bytes: Uint8Array | ArrayBuffer): Promise<PdfiumImage> {
return this._decodeImage(
bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes),
"image/png",View on GitHub (pinned to 9ef20dcab8)
Solutions
- Validate dimensions before calling `addPage`: `Number.isFinite(width) && Number.isFinite(height) && width > 0 && height > 0`, clamping to sane bounds (e.g. 1–14400 pt).
- Guard against using a disposed document: track a `_disposed` flag and throw a clearer error if `addPage` is called after `dispose()`.
- On null pagePtr, call `FPDF_GetLastError()` to capture the reason (this code currently does not).
- Audit upstream callers for unguarded `parseFloat`/division that could yield NaN.
Example fix
// before
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");
...
}
// after
addPage(dimensions: [number, number]): PdfiumPage {
const [width, height] = dimensions;
if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
throw new Error(`PdfiumDocument.addPage: invalid dimensions [${width}, ${height}]`);
}
const insertIdx = this._pages.length;
const pagePtr = this._m.FPDFPage_New(this._docPtr, insertIdx, width, height);
if (!pagePtr) {
const err = this._m.FPDF_GetLastError?.() ?? "unknown";
throw new Error(`PDFium: failed to create page (error ${err})`);
}
...
} Defensive patterns
Strategy: validation
Validate before calling
// Validate dimensions before addPage
function validDims(w: number, h: number): boolean {
return Number.isFinite(w) && Number.isFinite(h) && w > 0 && h > 0 && w <= 14400 && h <= 14400;
} Type guard
function isFinitePositiveDimensions(d: [number, number]): boolean {
return Array.isArray(d) && d.length === 2 && d.every(n => Number.isFinite(n) && n > 0);
} Try / catch
try {
doc.addPage([w, h]);
} catch (e) {
if (e instanceof Error && /invalid dimensions/.test(e.message)) {
doc.addPage([595.276, 841.89]); // fall back to A4
} else throw e;
} Prevention
- Validate width/height are finite and positive before calling addPage.
- Clamp absurd values to a sane page-size range (e.g. 1–14400 pt).
- Guard against calling addPage on a disposed PdfiumDocument (track a _disposed flag).
- Capture FPDF_GetLastError() on failure for a real cause.
When it happens
Trigger: Passing `[0, 0]`, negative dimensions, `NaN` (e.g. from a failed `parseFloat`), `Infinity`, or values outside PDFium's expected point range; calling `addPage` after the document pointer was closed/corrupted; WASM heap exhaustion at page allocation.
Common situations: Page dimensions sourced from a malformed PDF page object (e.g. a corrupt `getViewport` returning 0); a calculation that divided by zero; using a closed `PdfiumDocument` whose `_docPtr` was already freed.
Related errors
- PDFium: failed to create document
- PDFium: failed to open document (error ${err})
- PDFium: failed to load page ${pageIndex}
- PDFium: failed to create page
- Failed to load page ${pageIndex}
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/7a0480f5332e6c83.
Report an issue: GitHub.