{"record":{"id":"a1d40d43d8f9b7f1","repo":"mozilla/pdf.js","slug":"app-activedocs-is-read-only","errorCode":null,"errorMessage":"app.activeDocs is read-only","messagePattern":"app\\.activeDocs is read-only","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/scripting_api/app.js","lineNumber":189,"sourceCode":"      case \"no\":\n        return \"NOR\";\n      case \"pt\":\n        return sub === \"br\" ? \"PTB\" : \"ENU\";\n      case \"fi\":\n        return \"SUO\";\n      case \"SV\":\n        return \"SVE\";\n      default:\n        return \"ENU\";\n    }\n  }\n\n  get activeDocs() {\n    return [this._document.wrapped];\n  }\n\n  set activeDocs(_) {\n    throw new Error(\"app.activeDocs is read-only\");\n  }\n\n  get calculate() {\n    return this._document.obj.calculate;\n  }\n\n  set calculate(calculate) {\n    this._document.obj.calculate = calculate;\n  }\n\n  get constants() {\n    return (this._constants ??= Object.freeze({\n      align: Object.freeze({\n        left: 0,\n        center: 1,\n        right: 2,\n        top: 3,\n        bottom: 4,","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/scripting_api/app.js#L171-L207","documentation":"PDF.js's scripting API (Acrobat JavaScript sandbox) implements app.activeDocs as a read-only property: the getter returns an array containing the wrapped document, and the setter unconditionally throws. This matches the Acrobat JS spec, where activeDocs reflects the open documents and cannot be assigned. The throw fires on any assignment to app.activeDocs from PDF-embedded JavaScript or direct API use.","triggerScenarios":"A PDF's embedded JavaScript (or a caller of the pdf.js scripting API) executes app.activeDocs = [...] or otherwise assigns to the property. The setter at src/scripting_api/app.js:189 ignores its argument and always throws.","commonSituations":"PDF forms authored for Acrobat that attempt to cache or override the active-documents list; test harnesses that programmatically poke scripting-API properties; scripts ported from environments where activeDocs was writable.","solutions":["Remove the assignment to app.activeDocs in the PDF JavaScript; read the property instead.","If you need a custom documents list, store it in a separate variable rather than reassigning the API property.","Audit the PDF's embedded JS for accidental writes to read-only app properties."],"exampleFix":"// before\napp.activeDocs = [myDoc];\n// after\nconst docs = app.activeDocs; // read-only; do not assign","handlingStrategy":"validation","validationCode":"// app.activeDocs is read-only by spec; never assign.\n// Validate that you only READ it:\nfunction getActiveDocs(app) {\n  if (typeof app.activeDocs !== 'object' && app.activeDocs !== null) {\n    throw new TypeError('Expected activeDocs to be an array');\n  }\n  return app.activeDocs;\n}","typeGuard":"const isAppReadOnlyProp = (app, prop) =>\n  ['activeDocs','constants','formsVersion','fromPDFConverters','fs',\n   'language','media','monitors','numPlugins','platform','plugins',\n   'printColorProfiles','printerNames','thermometer','viewerType',\n   'viewerVariation','viewerVersion'].includes(prop) &&\n  (Object.getOwnPropertyDescriptor(Object.getPrototypeOf(app), prop)?.set != null);","tryCatchPattern":"// Reading is always safe; only assignments throw. Wrap any code that\n// may inadvertently assign:\ntry { /* code that touches app.activeDocs */ }\ncatch (e) { if (!/read-only/.test(e.message)) throw e; console.warn(e.message); }","preventionTips":["Treat the entire app.* surface in src/scripting_api/app.js as read-only unless the setter explicitly stores a value (focusRect, openInPlace, toolbar, etc.).","Lint document JavaScript for assignment to known read-only app properties before shipping.","In tests, never overwrite app properties; mock at the underlying send/_externalCall layer."],"tags":["scripting-api","read-only","acrobat-js","pdf-form"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}