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
- Read the value (`var n = doc.numPages;`) instead of writing it.
- 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).
- 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
- Page count is read-only; mutate pages via dedicated APIs, never by assignment.
- Static-lint scripts for `doc.numPages =` before dispatching to the sandbox.
- Run untrusted scripts under try/catch so a stray assignment does not abort the form.
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
- doc.mouseX is read-only
- doc.mouseY is read-only
- doc.numFields is read-only
- doc.numTemplates is read-only
- doc.outerAppWindowRect is read-only
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/46b3aadf26c182e4.
Report an issue: GitHub.