{"record":{"id":"7aac9779a932eaff","repo":"parallax/jsPDF","slug":"objectid-must-be-passed-to-putstream-for-file-encr","errorCode":null,"errorMessage":"ObjectId must be passed to putStream for file encryption","messagePattern":"ObjectId must be passed to putStream for file encryption","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/jspdf.js","lineNumber":1773,"sourceCode":"  });\n\n  var getFilters = (API.__private__.getFilters = function() {\n    return filters;\n  });\n\n  var putStream = (API.__private__.putStream = function(options) {\n    options = options || {};\n    var data = options.data || \"\";\n    var filters = options.filters || getFilters();\n    var alreadyAppliedFilters = options.alreadyAppliedFilters || [];\n    var addLength1 = options.addLength1 || false;\n    var valueOfLength1 = data.length;\n    var objectId = options.objectId;\n    var encryptor = function(data) {\n      return data;\n    };\n    if (encryptionOptions !== null && typeof objectId == \"undefined\") {\n      throw new Error(\n        \"ObjectId must be passed to putStream for file encryption\"\n      );\n    }\n    if (encryptionOptions !== null) {\n      encryptor = encryption.encryptor(objectId, 0);\n    }\n\n    var processedData = {};\n    if (filters === true) {\n      filters = [\"FlateEncode\"];\n    }\n    var keyValues = options.additionalKeyValues || [];\n    if (typeof jsPDF.API.processDataByFilters !== \"undefined\") {\n      processedData = jsPDF.API.processDataByFilters(data, filters);\n    } else {\n      processedData = { data: data, reverseChain: [] };\n    }\n    var filterAsString =","sourceCodeStart":1755,"sourceCodeEnd":1791,"githubUrl":"https://github.com/parallax/jsPDF/blob/a3930ce03a585a26b2c76d12a0f413ce96f6d1a3/src/jspdf.js#L1755-L1791","documentation":"`putStream` (src/jspdf.js:1761) writes a PDF stream object and, when encryption is enabled (`options.encryption` passed to the constructor, see src/jspdf.js:228), it must encrypt the stream — which requires the stream's object id. The guard at src/jspdf.js:1772 throws if `encryptionOptions !== null` but `options.objectId` is undefined. This is normally an internal invariant: every stream-writing call site supplies an objectId. A user hits it when a plugin or custom output hook calls `doc.internal.__private__.putStream({ data })` directly without an objectId on an encrypted document.","triggerScenarios":"Creating `new jsPDF({ encryption: {...} })` and then a plugin/form-integration calls `putStream` without `objectId`; monkey-patching the output pipeline and dropping the objectId; acroform or annotation code paths that don't thread objectId through on encrypted docs.","commonSituations":"Third-party plugins that weren't written with encryption in mind; custom stream injection during output; bugs in plugin versions that predate encryption support.","solutions":["If calling putStream directly on an encrypted doc, always pass `options.objectId` (a valid allocated object number).","Update third-party plugins to versions that support encryption (they must thread objectId into putStream).","If you don't actually need encryption, remove the `encryption` option from the constructor.","Allocate an object id via the internal API (`doc.internal.newObject`) and pass it through."],"exampleFix":"// before (encrypted doc, plugin omits id)\n doc.internal.__private__.putStream({ data: streamBytes });  // throws\n\n// after\n var objId = doc.internal.newObject();\n doc.internal.__private__.putStream({ data: streamBytes, objectId: objId });","handlingStrategy":"validation","validationCode":"function putStreamSafe(doc, opts) {\n  var enc = doc.internal.__private__.encryptor;\n  if (enc && (opts.objectId == null)) {\n    opts.objectId = doc.internal.newObject(); // allocate before writing\n  }\n  return doc.internal.__private__.putStream(opts);\n}","typeGuard":"function hasObjectIdForEncryption(doc, opts) {\n  // encryption is active when doc.internal.security exists\n  return !(doc.internal.security && (opts.objectId == null));\n}","tryCatchPattern":"try {\n  doc.internal.__private__.putStream({ data: bytes });\n} catch (e) {\n  if (/ObjectId must be passed/.test(e.message)) {\n    var id = doc.internal.newObject();\n    doc.internal.__private__.putStream({ data: bytes, objectId: id });\n  } else throw e;\n}","preventionTips":["On encrypted documents, always pass options.objectId when calling putStream directly.","Update plugins to versions that support encryption (thread objectId through).","If encryption isn't required, omit the encryption option to avoid the constraint."],"tags":["encryption","stream","putstream","objectid","internal"],"backgroundTag":null,"analyzedSha":"a3930ce03a585a26b2c76d12a0f413ce96f6d1a3","analyzedAt":"2026-08-13T05:33:39.648Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}