{"record":{"id":"50c7ec9202476fd1","repo":"parallax/jsPDF","slug":"putcatalogcallback-root-missing","errorCode":null,"errorMessage":"putCatalogCallback: Root missing.","messagePattern":"putCatalogCallback: Root missing\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/modules/acroform.js","lineNumber":534,"sourceCode":"};\n\n// Callbacks\n\nvar putCatalogCallback = function(scope) {\n  // Put reference to AcroForm to DocumentCatalog\n  if (\n    typeof scope.internal.acroformPlugin.acroFormDictionaryRoot !== \"undefined\"\n  ) {\n    // for safety, shouldn't normally be the case\n    scope.internal.write(\n      \"/AcroForm \" +\n        scope.internal.acroformPlugin.acroFormDictionaryRoot.objId +\n        \" \" +\n        0 +\n        \" R\"\n    );\n  } else {\n    throw new Error(\"putCatalogCallback: Root missing.\");\n  }\n};\n\n/**\n * Adds /Acroform X 0 R to Document Catalog, and creates the AcroForm\n * Dictionary\n */\nvar AcroFormDictionaryCallback = function(scope) {\n  // Remove event\n  scope.internal.events.unsubscribe(\n    scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID\n  );\n  delete scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID;\n  scope.internal.acroformPlugin.printedOut = true;\n};\n\n/**\n * Creates the single Fields and writes them into the Document","sourceCodeStart":516,"sourceCodeEnd":552,"githubUrl":"https://github.com/parallax/jsPDF/blob/a3930ce03a585a26b2c76d12a0f413ce96f6d1a3/src/modules/acroform.js#L516-L552","documentation":"Thrown by the putCatalogCallback during PDF output when scope.internal.acroformPlugin.acroFormDictionaryRoot is undefined. This callback writes the /AcroForm reference into the document catalog, so a missing root means the AcroForm plugin state was not initialized or was lost before output. It is an internal-state-consistency error, not a normal user error.","triggerScenarios":"Calling doc.output() / doc.save() when the AcroForm plugin's dictionary root was never created (e.g. the catalog callback fires but initializeAcroForm did not run), or when internal state was reset between adding fields and output.","commonSituations":"A bug in field initialization ordering; reusing a jsPDF instance after a partial reset; an AcroForm module version mismatch; calling output on a document where addField failed silently.","solutions":["Ensure at least one AcroForm field is added via doc.addField(...) before output so initializeAcroForm runs.","Verify scope.internal.acroformPlugin and its acroFormDictionaryRoot are defined before output in custom workflows.","If you do not need forms, avoid loading the acroform module; if you do, follow the documented field-add sequence.","Wrap doc.output() in try/catch to surface the state error gracefully."],"exampleFix":"// before\ndoc.output('arraybuffer'); // no field added -> putCatalogCallback throws\n\n// after\nvar field = new doc.AcroFormField();\nfield.FT = '/Tx';\nfield.T = 'Name';\nfield.Rect = [10, 10, 100, 30];\ndoc.addField(field);\ndoc.output('arraybuffer');","handlingStrategy":"try-catch","validationCode":"function ensureAcroFormReady(doc) {\n  var p = doc.internal && doc.internal.acroformPlugin;\n  if (!p || typeof p.acroFormDictionaryRoot === 'undefined') {\n    throw new Error('AcroForm plugin not initialized; add at least one field before output');\n  }\n}\nensureAcroFormReady(doc);","typeGuard":"function hasAcroFormRoot(doc) {\n  return !!(doc.internal && doc.internal.acroformPlugin &&\n            doc.internal.acroformPlugin.acroFormDictionaryRoot);\n}","tryCatchPattern":"try {\n  return doc.output('arraybuffer');\n} catch (e) {\n  if (/putCatalogCallback: Root missing/.test(e.message)) {\n    throw new Error('No AcroForm fields were added before output');\n  }\n  throw e;\n}","preventionTips":["Add at least one field via doc.addField before calling output/save.","Follow the documented AcroForm field-add sequence.","Do not load the acroform module if you do not intend to use forms."],"tags":["acroform","internal","pdf-output","state"],"backgroundTag":null,"analyzedSha":"a3930ce03a585a26b2c76d12a0f413ce96f6d1a3","analyzedAt":"2026-08-13T05:33:39.648Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}