DocGen Debt: The Salesforce Customization That Exists Only for Your Documents

Every field, flow, and object you built because your document tool could not produce the document you needed is a liability you keep paying for. Here is how to recognize docgen debt, audit how much your org carries, and stop creating more of it.
Open your field list on the Quote or Invoice object and look for the ones with Display, Formatted, Text, or Print in the name. Ask what happens if you delete one.
If the honest answer is "the PDF breaks and I am not sure what else," you have found docgen debt.
DocGen debt is all the Salesforce customization that exists only because your document generation tool could not produce the document you needed. Not because the business needed the data. Not because a process required it. Because a template could not do something, and the org absorbed the difference.
Like any technical debt, the individual decisions were reasonable. Also like any technical debt, you pay interest on every one of them, forever, and you usually start noticing when someone new asks a question you cannot answer.
What it looks like
Fields are the most common form by a wide margin, and they accumulate one small, defensible decision at a time:
- Need a formatted address? Create a formula field.
- Need a subtotal the template cannot calculate? Create another field.
- Need several values in one string because the template can only place one merge field? Another field.
- Need a status that only means something to the document? One more field.
- Need the lines in a particular order? A sort field, written by automation.
Individually, each of these is fifteen minutes of work and obviously harmless. Collectively, they are why nobody can safely change anything on that object.
But fields are only the visible layer. A mature org carries docgen debt in several forms:
| Layer | What it looks like | Why it exists |
|---|---|---|
| Data model | Formula fields, roll-up summaries, concatenation fields, sort and sequence fields, helper fields that became permanent | The template could not format, calculate, join, or order |
| Structure | Junction objects and custom objects that flatten a hierarchy | The template could not traverse a relationship, so the data was pre-flattened for it |
| Automation | Flows, Apex, and triggers that populate the fields above | Something has to keep the flattened copy in sync |
| Process | Validation rules and approval steps enforcing document-only requirements | The document breaks without a value, so the org forces one |
| Reporting | Reports and list views built purely as document data sources | The tool reads from a report rather than from the objects |
| Integration | Remote site settings, connected apps, integration users, permission sets | The document is assembled outside the org |
The automation row is the one people miss, and it is the most expensive. A flattened field is not free after it is created: something has to write to it, and now a change to how quotes are priced means a change to the docgen automation too, or the document quietly reports last month's number.
Why it is debt, not just configuration
Every custom field carries a fixed lifetime cost that has nothing to do with how useful it is. It has to be named, deployed through every environment, documented, granted field-level security across every profile and permission set, covered by tests if automation touches it, kept off the layouts where it does not belong, and explained to the next developer who asks:
"Why does
Invoice_Display_Address__ceven exist?"
That is the interest payment. You make it on every deployment, every security review, every onboarding, and every refactor, whether or not the document that justified the field is still in use.
Then there is the compounding, which is the part that turns a manageable annoyance into a structural problem.
Doc-layer fields get adopted by the business layer. Invoice_Display_Address__c is the only nicely formatted address on the object, so a report builder uses it. Then a dashboard uses the report. Then someone builds a validation rule against it. The field was created to serve a template, and it is now load-bearing in three places that have nothing to do with documents.
At that point the debt is no longer safe to pay down. You cannot delete the field, you cannot change how it is calculated without breaking a dashboard, and the document tool has become a permanent stakeholder in your data model. That is the state most mature orgs are actually in, and it is why "we will clean it up later" rarely happens.
The deeper cause is architectural. Placement-based templates model where a value sits on a page, not how your data is structured. Anything the template cannot traverse, calculate, or format has to be pre-chewed into a shape it can place, and your org is the only place to put it. The document tool cannot change your data model directly, so it changes it through you.
A 30-minute audit
You do not need a project to find out how much you carry. Try this on your two busiest document objects.
- Search field names for
Display,Formatted,Text,Print,PDF,Doc,Merge,Temp,Sort,Seq, and your vendor's name. Naming is honest more often than not. - Sort by created date and look at clusters. Six fields created on the same afternoon three years ago is usually one document going live.
- Find fields on no page layout. A field users never see, that automation or a template still reads, is a strong candidate.
- Check the descriptions. Blank descriptions correlate with fields created under deadline pressure for a document nobody documented.
- Open your templates and merge queries and list every field they reference. Anything in that list and nowhere else is docgen debt by definition.
- For each candidate, ask the deletion question: if this field vanished tonight, what breaks? Record the answer, including "I do not know," which is itself a finding.
Count what you find. That number is what the current document tool costs you beyond its license, and it is usually the most persuasive slide in the business case for changing anything.
Not all of it is debt
Be fair in the audit. A formatted address field that six teams use for six purposes has earned its place, whatever the original reason. A subtotal the business genuinely reports on is a legitimate field that a document happens to also use.
The test is not "did a document cause this to exist." It is "would we keep this if the document went away." If yes, it graduated into the business layer and should be documented as such, with an owner who is not the docgen project. If no, it is debt.
Paying it down without breaking production
Two rules make this survivable.
First, stop creating more. This matters more than any cleanup. If every new document still spawns three fields, you are bailing with the tap running. The only durable fix is that new documents stop requiring new customization, which is a property of the tool, not of your discipline.
Second, never bulk-delete. Work from a register, one item at a time, and deprecate before deleting: verify it is genuinely unused with a dependency check across reports, list views, flows, validation rules, and integrations; rename it with a ZZ_ prefix; remove it from layouts; wait a full business cycle. If nothing complains, delete it. If something does, you just learned it was not debt.
This is exactly the register and sequence described in the phased migration playbook, where you build the list during discovery and work it during decommissioning. Cleanup belongs at the end of a migration, not at the start of one: during the migration those fields are still holding your documents up.
What stops the debt from forming
If the cause is a template that cannot traverse, calculate, or format, then the fix is a template that can.
ZeroExport is a native, structure-aware document generation engine that runs entirely inside Salesforce as a managed package. The capabilities that map directly onto the debt categories above:
- Deep nested hierarchy rendering. The template binds the relationship path and renders the tree as real nested structure, so the junction objects and flattening rollups that existed to pre-chew a hierarchy stop being necessary.
- Auto-detected repeater boundaries. Repeating blocks form from the data with no manual loop markers, which removes a class of sort and sequence fields.
- Section-level visibility that cascades. A section and its header appear only when its condition is met, so document-only status fields driving field-visibility toggles have nothing left to do.
- Adaptive layout on missing data, so the layout reflows rather than leaving a gap, which is what validation rules were often quietly protecting against.
- Per-record override for the genuine one-off, instead of a field or a template variant to carry the exception.
- No middleware. It runs inside Salesforce, so the remote site settings, connected apps, and integration users in the integration row do not get created in the first place. This was the highest-demand capability across the roughly 2,900 discussions we analyzed (362 of them).
Being straight about limits, because a debt argument built on an over-claim is its own kind of liability: reusable blocks, meaning one structural section defined once and propagated across many templates, are on the roadmap and not shipped, so template consolidation today means one template per document family with conditional sections inside it. On raw rendering performance at very high volume and pixel-exact page-break control we publish no claims.
And the honest caveat on the debt you already have: no tool retroactively deletes your fields. What changes is the rate at which new ones appear, and whether the next document costs you three more.
FAQ
What is docgen debt?
DocGen debt is Salesforce customization that exists only because a document generation tool could not produce the document you needed: formula and concatenation fields, flattening rollups and junction objects, sort fields, the automation that maintains them, validation rules protecting a template from missing data, reports used as data sources, and the integration plumbing for anything assembled outside the org.
How do I tell docgen debt from a legitimate field?
Ask whether you would keep it if the document went away. If yes, it has graduated into the business layer and needs an owner and documentation. If no, it is debt. Origin does not decide this; current usage does.
Why are custom fields created for documents such a problem?
Each one carries a permanent cost: naming, deployment, documentation, field-level security across every profile and permission set, test coverage, and explanation to whoever comes next. Worse, doc-layer fields get adopted by reports, dashboards, and validation rules, after which they cannot safely be removed and your document tool has become a stakeholder in your data model.
How do I clean up docgen debt safely?
One item at a time, from a register, and never during the migration itself. Verify it is unused with a dependency check, rename it with a ZZ_ prefix, remove it from layouts, wait a full business cycle, then delete. Anything that complains during that window was not debt.
Will switching document tools remove the fields I already have?
No, and anyone promising that is overselling. Existing customization still has to be audited and retired deliberately. What a structure-aware engine changes is the rate of new debt: whether the next document requires three more fields or none.
Related Reading
- How to Migrate Off a Salesforce Document Generation Tool Without Breaking It
- The Salesforce Document Generation Workaround Tax
- The Hidden Logic Problem in Word-Based Salesforce Documents
- Build maintainable document workflows in Salesforce with ZeroExport
- Replace Fragile Word Templates with Logic-Driven Documents
Ready to try ZeroExport?
Start generating documents directly in your Salesforce org. No integrations, no setup overhead, no complexity.