{"record":{"id":"06aab14b19040882","repo":"mozilla/pdf.js","slug":"doc-producer-is-read-only","errorCode":null,"errorMessage":"doc.producer is read-only","messagePattern":"doc\\.producer is read-only","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/scripting_api/doc.js","lineNumber":607,"sourceCode":"\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\n  get requiresFullSave() {\n    return false;\n  }\n\n  set requiresFullSave(_) {\n    throw new Error(\"doc.requiresFullSave is read-only\");\n  }\n\n  get securityHandler() {\n    return this._securityHandler;\n  }\n\n  set securityHandler(_) {\n    throw new Error(\"doc.securityHandler is read-only\");\n  }\n","sourceCodeStart":589,"sourceCodeEnd":625,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/scripting_api/doc.js#L589-L625","documentation":"`Doc.producer` returns the producer string from the PDF metadata (`this._producer`), populated when the document is parsed. It is a factual metadata attribute and read-only per the Acrobat spec — changing it would misrepresent the file's origin. PDF.js's throwing setter enforces that; scripts cannot overwrite the producer.","triggerScenarios":"A script writes `doc.producer = 'MyApp';` to brand or alter metadata. The setter throws on assignment.","commonSituations":"Scripts that try to rewrite metadata on save; branding workflows ported from Acrobat; code that assumes metadata setters exist.","solutions":["Remove the assignment; read `doc.producer` only (`var p = doc.producer;`).","Perform metadata edits at the PDF-generation/processing layer (the producer is set by the creating application).","Run legacy scripts through try/catch to tolerate the write attempt."],"exampleFix":"// before\ndoc.producer = 'Custom Producer';\n\n// after\nvar p = doc.producer; // read-only metadata","handlingStrategy":"validation","validationCode":"const READ_ONLY_DOC_PROPS = new Set(['producer','subject','title','author','creator','keywords' /* ... */]);\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, 'producer'); // true","tryCatchPattern":"try {\n  doc.producer = 'Custom';\n} catch (e) {\n  if (/producer is read-only/.test(e.message)) console.warn(e.message);\n  else throw e;\n}","preventionTips":["Metadata fields are read-only in PDF.js scripting; edit metadata at PDF generation time.","Maintain and lint against a list of read-only metadata properties.","Wrap branding/metadata scripts in try/catch for legacy tolerance."],"tags":["scripting","acrobat-js-api","doc-object","read-only","metadata"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}