mozilla/pdf.js · error · Error
doc.sounds is read-only
Error message
doc.sounds is read-only
What it means
`Doc.sounds` returns the array of sound objects embedded in the document; PDF.js returns `[]` because sound assets are not surfaced to the scripting sandbox. It is read-only per the Acrobat spec — the sound collection is part of document content, not settable. The throwing setter enforces that contract.
Source
Thrown at src/scripting_api/doc.js:639
set securityHandler(_) {
throw new Error("doc.securityHandler is read-only");
}
get selectedAnnots() {
return [];
}
set selectedAnnots(_) {
throw new Error("doc.selectedAnnots is read-only");
}
get sounds() {
return [];
}
set sounds(_) {
throw new Error("doc.sounds is read-only");
}
get spellDictionaryOrder() {
return this._spellDictionaryOrder;
}
set spellDictionaryOrder(spellDictionaryOrder) {
this._spellDictionaryOrder = spellDictionaryOrder;
}
get spellLanguageOrder() {
return this._spellLanguageOrder;
}
set spellLanguageOrder(spellLanguageOrder) {
this._spellLanguageOrder = spellLanguageOrder;
}
View on GitHub (pinned to 5903d58d58)
Solutions
- Remove the assignment; read the value (`var s = doc.sounds;`, `[]` in PDF.js).
- Handle audio at the host integration layer if needed.
- Guard legacy scripts with try/catch.
Example fix
// before doc.sounds = [mySound]; // after var s = doc.sounds; // read-only; [] in PDF.js
Defensive patterns
Strategy: try-catch
Validate before calling
const READ_ONLY_DOC_PROPS = new Set(['sounds','selectedAnnots' /* ... */]);
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, 'sounds'); // true Try / catch
try {
doc.sounds = [sound];
} catch (e) {
if (/sounds is read-only/.test(e.message)) console.warn(e.message);
else throw e;
} Prevention
- Sound assets are not surfaced to PDF.js scripting; manage media at the host layer.
- Lint scripts for assignments to read-only media/collection properties.
- Wrap media-rich legacy scripts in try/catch.
When it happens
Trigger: A script writes `doc.sounds = [...];` to register or replace sounds. The setter throws immediately.
Common situations: Media-rich forms ported from Acrobat; code that plays sound on events and tries to manage the sound list; legacy interactive PDFs.
Related errors
- doc.numTemplates is read-only
- doc.outerAppWindowRect is read-only
- doc.outerDocWindowRect is read-only
- doc.pageWindowRect is read-only
- doc.requiresFullSave is read-only
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/2afa6e2d3a3f9e2f.
Report an issue: GitHub.