mozilla/pdf.js · error · Error
doc.URL is read-only
Error message
doc.URL is read-only
What it means
`Doc.URL` returns the URL from which the document was loaded (`this._URL`). It is read-only per the Acrobat spec — the source URL is a factual attribute of how the doc was opened, not settable by in-document scripts. PDF.js's throwing setter enforces that contract.
Source
Thrown at src/scripting_api/doc.js:687
set templates(_) {
throw new Error("doc.templates is read-only");
}
get title() {
return this._title;
}
set title(_) {
throw new Error("doc.title is read-only");
}
get URL() {
return this._URL;
}
set URL(_) {
throw new Error("doc.URL is read-only");
}
get viewState() {
return undefined;
}
set viewState(_) {
throw new Error("doc.viewState is read-only");
}
get xfa() {
return this._xfa;
}
set xfa(_) {
throw new Error("doc.xfa is read-only");
}
View on GitHub (pinned to 5903d58d58)
Solutions
- Remove the assignment; read the value (`var u = doc.URL;`).
- Control the source URL from the embedding page / `getDocument` call rather than from inside a document script.
- Wrap script execution in try/catch.
Example fix
// before doc.URL = 'https://example.com/doc.pdf'; // after var u = doc.URL; // read-only source URL
Defensive patterns
Strategy: validation
Validate before calling
const READ_ONLY_DOC_PROPS = new Set(['URL','path' /* ... */]);
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, 'URL'); // true Try / catch
try {
doc.URL = 'https://example.com/doc.pdf';
} catch (e) {
if (/\\bURL is read-only/.test(e.message)) console.warn(e.message);
else throw e;
} Prevention
- Source URL/path is set by how the doc is loaded; control it from `getDocument`/the embedding page.
- Read `doc.URL` rather than writing it.
- Lint scripts for assignments to read-only source properties.
When it happens
Trigger: A script writes `doc.URL = 'https://...';` to redirect or record the source. The setter throws on that line.
Common situations: Scripts that try to force a reload from a new URL; branding/audit code that rewrites the URL field; legacy scripts ported from a local-file context.
Related errors
- doc.mouseX is read-only
- doc.mouseY is read-only
- doc.numFields is read-only
- doc.numPages is read-only
- doc.numTemplates is read-only
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/2cd1d638edd57a88.
Report an issue: GitHub.