{"record":{"id":"eb451639875a7754","repo":"mozilla/pdf.js","slug":"doc-path-is-read-only","errorCode":null,"errorMessage":"doc.path is read-only","messagePattern":"doc\\.path is read-only","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/scripting_api/doc.js","lineNumber":591,"sourceCode":"    }\n    this._send({ command: \"page-num\", value });\n    this._pageNum = value;\n  }\n\n  get pageWindowRect() {\n    return [0, 0, 0, 0];\n  }\n\n  set pageWindowRect(_) {\n    throw new Error(\"doc.pageWindowRect is read-only\");\n  }\n\n  get path() {\n    return \"\";\n  }\n\n  set path(_) {\n    throw new Error(\"doc.path is read-only\");\n  }\n\n  get permStatusReady() {\n    return true;\n  }\n\n  set permStatusReady(_) {\n    throw new Error(\"doc.permStatusReady is read-only\");\n  }\n\n  get producer() {\n    return this._producer;\n  }\n\n  set producer(_) {\n    throw new Error(\"doc.producer is read-only\");\n  }\n","sourceCodeStart":573,"sourceCodeEnd":609,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/scripting_api/doc.js#L573-L609","documentation":"`Doc.path` returns the device-independent path of the open document; PDF.js returns `\"\"` because documents loaded in a browser have no filesystem path. It is read-only per the Acrobat spec — the path is a factual attribute of how the doc was opened, not something a script can change. The throwing setter enforces that contract.","triggerScenarios":"A script writes `doc.path = '/some/file.pdf';`, typically to record or fake a save location. The setter throws immediately.","commonSituations":"Save/export scripts ported from desktop Acrobat; scripts trying to derive a working directory from `doc.path`; code that assumes a writable path field.","solutions":["Remove the assignment; read `doc.path` (returns `\"\"` in PDF.js) or `doc.URL` for the source location.","Manage save paths at the host integration layer rather than inside the document script.","Wrap script execution in try/catch to tolerate legacy save code."],"exampleFix":"// before\ndoc.path = '/tmp/saved.pdf';\n\n// after\nvar src = doc.URL; // read-only source; doc.path returns '' in browser","handlingStrategy":"validation","validationCode":"const READ_ONLY_DOC_PROPS = new Set(['path','URL' /* ... */]);\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, 'path'); // true","tryCatchPattern":"try {\n  doc.path = '/tmp/saved.pdf';\n} catch (e) {\n  if (/\\\\bpath is read-only/.test(e.message)) console.warn(e.message);\n  else throw e;\n}","preventionTips":["`doc.path` is a factual load attribute; manage save paths at the host layer.","Read `doc.path`/`doc.URL` instead of writing them.","Lint scripts for assignments to read-only path properties before dispatch."],"tags":["scripting","acrobat-js-api","doc-object","read-only","path","filesystem"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}