{"record":{"id":"a412ebe2f67d6c90","repo":"mozilla/pdf.js","slug":"doc-viewstate-is-read-only","errorCode":null,"errorMessage":"doc.viewState is read-only","messagePattern":"doc\\.viewState is read-only","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/scripting_api/doc.js","lineNumber":695,"sourceCode":"\n  set title(_) {\n    throw new Error(\"doc.title is read-only\");\n  }\n\n  get URL() {\n    return this._URL;\n  }\n\n  set URL(_) {\n    throw new Error(\"doc.URL is read-only\");\n  }\n\n  get viewState() {\n    return undefined;\n  }\n\n  set viewState(_) {\n    throw new Error(\"doc.viewState is read-only\");\n  }\n\n  get xfa() {\n    return this._xfa;\n  }\n\n  set xfa(_) {\n    throw new Error(\"doc.xfa is read-only\");\n  }\n\n  get XFAForeground() {\n    return false;\n  }\n\n  set XFAForeground(_) {\n    throw new Error(\"doc.XFAForeground is read-only\");\n  }\n","sourceCodeStart":677,"sourceCodeEnd":713,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/scripting_api/doc.js#L677-L713","documentation":"`Doc.viewState` returns the document's view state (used to capture/restore the viewing position); PDF.js returns `undefined` because it does not expose a serializable view-state object to the scripting sandbox. It is read-only per the Acrobat spec — view state is observed, not assigned through this property (restoration uses dedicated APIs). The throwing setter enforces that contract.","triggerScenarios":"A script writes `doc.viewState = {...};`, attempting to capture or force a view state. The setter throws on assignment.","commonSituations":"Layout-restore scripts ported from Acrobat; code that snapshots view state on close; tutorials that demonstrate unsupported writes.","solutions":["Remove the assignment; read the value (`var v = doc.viewState;`, `undefined` in PDF.js).","Implement view capture/restore at the host viewer layer (scroll/zoom/page state) instead of via this property.","Run legacy scripts through try/catch."],"exampleFix":"// before\ndoc.viewState = { page: 1, zoom: 1.5 };\n\n// after\nvar v = doc.viewState; // read-only; undefined in PDF.js","handlingStrategy":"try-catch","validationCode":"const READ_ONLY_DOC_PROPS = new Set(['viewState','pageWindowRect' /* ... */]);\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, 'viewState'); // true","tryCatchPattern":"try {\n  doc.viewState = { page: 1, zoom: 1.5 };\n} catch (e) {\n  if (/viewState is read-only/.test(e.message)) console.warn(e.message);\n  else throw e;\n}","preventionTips":["View state is not serialized to the scripting sandbox; capture/restore it at the viewer layer.","Lint scripts for assignments to read-only view/window properties.","Wrap layout-restore scripts in try/catch."],"tags":["scripting","acrobat-js-api","doc-object","read-only","view-state","unsupported"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}