{"record":{"id":"2afa6e2d3a3f9e2f","repo":"mozilla/pdf.js","slug":"doc-sounds-is-read-only","errorCode":null,"errorMessage":"doc.sounds is read-only","messagePattern":"doc\\.sounds is read-only","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/scripting_api/doc.js","lineNumber":639,"sourceCode":"\n  set securityHandler(_) {\n    throw new Error(\"doc.securityHandler is read-only\");\n  }\n\n  get selectedAnnots() {\n    return [];\n  }\n\n  set selectedAnnots(_) {\n    throw new Error(\"doc.selectedAnnots is read-only\");\n  }\n\n  get sounds() {\n    return [];\n  }\n\n  set sounds(_) {\n    throw new Error(\"doc.sounds is read-only\");\n  }\n\n  get spellDictionaryOrder() {\n    return this._spellDictionaryOrder;\n  }\n\n  set spellDictionaryOrder(spellDictionaryOrder) {\n    this._spellDictionaryOrder = spellDictionaryOrder;\n  }\n\n  get spellLanguageOrder() {\n    return this._spellLanguageOrder;\n  }\n\n  set spellLanguageOrder(spellLanguageOrder) {\n    this._spellLanguageOrder = spellLanguageOrder;\n  }\n","sourceCodeStart":621,"sourceCodeEnd":657,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/scripting_api/doc.js#L621-L657","documentation":"`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.","triggerScenarios":"A script writes `doc.sounds = [...];` to register or replace sounds. The setter throws immediately.","commonSituations":"Media-rich forms ported from Acrobat; code that plays sound on events and tries to manage the sound list; legacy interactive PDFs.","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."],"exampleFix":"// before\ndoc.sounds = [mySound];\n\n// after\nvar s = doc.sounds; // read-only; [] in PDF.js","handlingStrategy":"try-catch","validationCode":"const READ_ONLY_DOC_PROPS = new Set(['sounds','selectedAnnots' /* ... */]);\nfunction assertsNoReadOnlyWrite(scriptSrc) {\n  for (const p of READ_ONLY_DOC_PROPS) {\n    if (new RegExp(`\\\\bdoc\\\\.${p}\\\\s*=[^=]`).test(scriptSrc)) {\n      throw new Error(`Script writes read-only property doc.${p}`);\n    }\n  }\n}\nassertsNoReadOnlyWrite(myScript);","typeGuard":"function isReadOnlyDocProp(doc, prop) {\n  const desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(doc), prop)\n    || Object.getOwnPropertyDescriptor(doc, prop);\n  return !!desc && !!desc.get && !desc.set;\n}\nisReadOnlyDocProp(doc, 'sounds'); // true","tryCatchPattern":"try {\n  doc.sounds = [sound];\n} catch (e) {\n  if (/sounds is read-only/.test(e.message)) console.warn(e.message);\n  else throw e;\n}","preventionTips":["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."],"tags":["scripting","acrobat-js-api","doc-object","read-only","media","sound","unsupported"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}