mozilla/pdf.js · error · Error

doc.numPages is read-only

Error message

doc.numPages is read-only

What it means

`Doc.numPages` returns the number of pages in the document (`this._numPages`), set when the document is loaded. It is read-only by the Acrobat spec — page count changes only through page insertion/deletion APIs, never by assignment. PDF.js installs a throwing setter so a script that tries `doc.numPages = n` fails loudly and consistently with Acrobat.

Source

Thrown at src/scripting_api/doc.js:534

  set nocache(nocache) {
    this._nocache = nocache;
  }

  get numFields() {
    return this._numFields;
  }

  set numFields(_) {
    throw new Error("doc.numFields is read-only");
  }

  get numPages() {
    return this._numPages;
  }

  set numPages(_) {
    throw new Error("doc.numPages is read-only");
  }

  get numTemplates() {
    return 0;
  }

  set numTemplates(_) {
    throw new Error("doc.numTemplates is read-only");
  }

  get outerAppWindowRect() {
    return [0, 0, 0, 0];
  }

  set outerAppWindowRect(_) {
    throw new Error("doc.outerAppWindowRect is read-only");
  }

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Read the value (`var n = doc.numPages;`) instead of writing it.
  2. Use the appropriate page add/delete APIs exposed by your integration if page mutation is required (PDF.js does not expose `newPage`/`deletePages` in the scripting sandbox).
  3. Wrap script execution in try/catch so a stray assignment is logged and ignored.

Example fix

// before
doc.numPages = 10;

// after
var pages = doc.numPages; // read-only, reflects actual page count
Defensive patterns

Strategy: validation

Validate before calling

const READ_ONLY_DOC_PROPS = new Set(['numPages','numFields' /* ... */]);
function assertsNoReadOnlyWrite(scriptSrc) {
  for (const p of READ_ONLY_DOC_PROPS) {
    if (new RegExp(`\\bdoc\\.${p}\\s*=[^=]`).test(scriptSrc)) {
      throw new Error(`Script writes read-only property doc.${p}`);
    }
  }
}
assertsNoReadOnlyWrite(myScript);

Type guard

function isReadOnlyDocProp(doc, prop) {
  const desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(doc), prop)
    || Object.getOwnPropertyDescriptor(doc, prop);
  return !!desc && !!desc.get && !desc.set;
}
isReadOnlyDocProp(doc, 'numPages'); // true

Try / catch

try {
  doc.numPages = 10;
} catch (e) {
  if (/numPages is read-only/.test(e.message)) console.warn(e.message);
  else throw e;
}

Prevention

When it happens

Trigger: A script assigns to `doc.numPages` (e.g. `doc.numPages = 5;`), typically from a mistaken belief that it resizes the document. The setter throws on that line.

Common situations: Scripts ported from engines where page count is settable; form-init code trying to fix a page count; copy-pasted snippet from a non-PDFjs tutorial.

Related errors


AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13). Data as JSON: /api/errors/46b3aadf26c182e4. Report an issue: GitHub.