{"record":{"id":"a0ec352e07201958","repo":"mozilla/pdf.js","slug":"app-constants-is-read-only","errorCode":null,"errorMessage":"app.constants is read-only","messagePattern":"app\\.constants is read-only","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/scripting_api/app.js","lineNumber":213,"sourceCode":"\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,\n      }),\n    }));\n  }\n\n  set constants(_) {\n    throw new Error(\"app.constants is read-only\");\n  }\n\n  get focusRect() {\n    return this._focusRect;\n  }\n\n  set focusRect(val) {\n    /* TODO or not */\n    this._focusRect = val;\n  }\n\n  get formsVersion() {\n    return FORMS_VERSION;\n  }\n\n  set formsVersion(_) {\n    throw new Error(\"app.formsVersion is read-only\");\n  }","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/scripting_api/app.js#L195-L231","documentation":"app.constants is a lazily-built, Object.freeze'd namespace (currently exposing align.left/center/right/top/bottom). Because it is a fixed enumeration surface in the Acrobat JS API, PDF.js freezes it and makes the setter throw. Any assignment to app.constants is rejected.","triggerScenarios":"PDF JavaScript or test code runs app.constants = {...} or attempts app.constants.align = .... Reassigning the property triggers the setter throw at src/scripting_api/app.js:213; mutating inner frozen objects throws a separate TypeError from Object.freeze.","commonSituations":"Scripts that try to extend the constants enumeration with custom alignment values; authors confusing app.constants with a user-extensible config object.","solutions":["Do not assign to app.constants; treat it as a frozen enumeration.","Define your own module-level constants object for any custom values.","Read app.constants.align.<name> only for the supported keys (left, center, right, top, bottom)."],"exampleFix":"// before\napp.constants = { align: { left: 0 } };\n// after\nconst myAlign = { left: 0 }; // keep custom constants separate","handlingStrategy":"validation","validationCode":"// app.constants is frozen and read-only.\nfunction safeConstant(app, group, key) {\n  const c = app.constants;\n  if (!c || !Object.isFrozen(c)) throw new Error('Unexpected constants shape');\n  return c?.[group]?.[key];\n}","typeGuard":"const isReadOnlyAppProp = (prop) =>\n  Object.getOwnPropertyDescriptor(App.prototype, prop)?.set?.name === '';\n// (setter is an arrow-less throw stub; alternatively maintain an explicit list)","tryCatchPattern":"try { /* code that may assign app.constants */ }\ncatch (e) { if (!/constants is read-only/.test(e.message)) throw e; }","preventionTips":["Maintain a denylist of read-only app.* property names and statically check PDF JS against it.","Use Object.freeze on your own constants rather than reusing app.constants.","Read app.constants.align.* only for the documented keys."],"tags":["scripting-api","read-only","frozen-object","acrobat-js"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}