{"record":{"id":"fe3270ee822f50eb","repo":"mozilla/pdf.js","slug":"doc-documentfilename-is-read-only","errorCode":null,"errorMessage":"doc.documentFileName is read-only","messagePattern":"doc\\.documentFileName is read-only","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/scripting_api/doc.js","lineNumber":343,"sourceCode":"\n  set disclosed(disclosed) {\n    this._disclosed = disclosed;\n  }\n\n  get docID() {\n    return this._docID;\n  }\n\n  set docID(_) {\n    throw new Error(\"doc.docID is read-only\");\n  }\n\n  get documentFileName() {\n    return this._documentFileName;\n  }\n\n  set documentFileName(_) {\n    throw new Error(\"doc.documentFileName is read-only\");\n  }\n\n  get dynamicXFAForm() {\n    return false;\n  }\n\n  set dynamicXFAForm(_) {\n    throw new Error(\"doc.dynamicXFAForm is read-only\");\n  }\n\n  get external() {\n    // According to the specification this should be `true` in non-Acrobat\n    // applications, however we ignore that to avoid bothering users with\n    // an `alert`-dialog on document load (see issue 15509).\n    return DOC_EXTERNAL;\n  }\n\n  set external(_) {","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/scripting_api/doc.js#L325-L361","documentation":"PDF.js's scripting sandbox (src/scripting_api) implements the Acrobat JavaScript `doc` object inside a QuickJS sandbox. Per the Acrobat API specification this property is read-only, so the class defines a getter that returns the current value and a setter that unconditionally throws `Error(\"doc.<prop> is read-only\")`. The throw aborts the currently executing sandboxed script event and is reported back to the host. `documentFileName` is the filename of the open PDF (seeded from `data.filename`); the script cannot rename the open document.","triggerScenarios":"A sandboxed PDF form/script executes an assignment to the property, e.g. `doc.documentFileName = value;` or `doc.documentFileName++`. Because the setter always throws (there is no condition), any write attempt triggers it.","commonSituations":"Scripts ported from desktop Acrobat where the filename could be set from script; forms that try to stamp runtime state into document metadata on save/open; and PDFs generated by tools that emit non-spec-compliant JavaScript.","solutions":["Remove the assignment to `doc.documentFileName`; read it through the getter instead.","Rename the file on disk before opening; pdf.js will then report the new name.","If you cannot edit the PDF's embedded script, wrap the statement in try/catch so the rest of the form logic still runs."],"exampleFix":"// before\ndoc.documentFileName = \"renamed.pdf\";\n// after\n// documentFileName is read-only — drop the assignment; read via doc.documentFileName","handlingStrategy":"validation","validationCode":"// Known read-only doc properties (PDF.js scripting_api/doc.js)\nconst READONLY_DOC_PROPS = new Set([\n  'author','bookmarkRoot','creator','dataObjects','docID',\n  'documentFileName','dynamicXFAForm','external','filesize','hidden',\n  'hostContainer','icons','info','innerAppWindowRect','innerDocWindowRect',\n  'isModal','keywords','modDate'\n]);\nif (READONLY_DOC_PROPS.has('documentFileName')) {\n  // skip the write; documentFileName is read-only in pdf.js\n  console.warn('doc.documentFileName is read-only in pdf.js');\n} else {\n  doc.documentFileName = value;\n}","typeGuard":"// Known read-only doc properties (PDF.js scripting_api/doc.js)\nconst READONLY_DOC_PROPS = new Set([\n  'author','bookmarkRoot','creator','dataObjects','docID',\n  'documentFileName','dynamicXFAForm','external','filesize','hidden',\n  'hostContainer','icons','info','innerAppWindowRect','innerDocWindowRect',\n  'isModal','keywords','modDate'\n]);\nconst isReadOnlyDocProp = (name) => READONLY_DOC_PROPS.has(name);\n// usage: if (!isReadOnlyDocProp('keywords')) doc.keywords = v;","tryCatchPattern":"try {\n  doc.documentFileName = value;\n} catch (e) {\n  // pdf.js throws Error('doc.documentFileName is read-only')\n  if (/is read-only/.test(e.message)) { /* swallow, expected */ }\n  else { throw e; }\n}","preventionTips":["Treat every property listed in the Acrobat JS reference as read-only unless pdf.js provides a setter that stores the value.","Before assigning, check `isReadOnlyDocProp('documentFileName')` or grep the setter in src/scripting_api/doc.js for a `throw`.","When porting scripts from Acrobat, run them against the pdf.js sandbox in the dev server first to surface writes early.","Prefer reading metadata through the Info dictionary at PDF authoring time rather than mutating it from a script."],"tags":["scripting","acrobat-api","read-only"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}