Between a form fill and a closed-won opportunity, who gets to write to the record? Trace a single won deal backwards through field-level history and the number comes out higher than anyone on the team guessed. Each of those handoffs is a translation. Translations lose things.
Data quality work goes wrong when it starts from the symptom. Someone exports the account object, finds eleven hundred records with no industry populated, and books a cleanup sprint. The sprint fills the field. Four months later the same export has nine hundred blanks, because nothing changed about the moment where industry was supposed to get captured.
Count the handoffs before you count the errors
Take one deal and walk it through every system that touched it. The path is rarely as short as the architecture diagram suggests:
- The form writes into Marketo or HubSpot, where a free-text company name becomes the string that everything downstream will try to match against.
- The sync pushes a lead into Salesforce, and dedup logic decides in that instant whether it joins an existing account or opens a new one.
- An SDR qualifies it and retypes the job title by hand, because what the form captured was "Marketing" and the real title is Director of Demand Generation.
- An account executive converts the lead, which collapses some fields into the contact object, carries others onto the opportunity, and silently drops whatever the conversion mapping never covered.
- Overnight, an enrichment job runs over the finished record and rewrites the parts it believes it knows better.
Five handoffs, five chances for the record to become slightly less true. The errors cluster there, and no amount of downstream cleaning touches the cause. The dashboard you get asked to explain in Looker or Tableau, built on a Snowflake copy of all of it, is reading the residue of those five moments, which is why defending it feels like defending somebody else's typing.
Duplicates are a matching problem before they are a cleanup problem
Every team that complains about duplicates has already run a merge job. The merge works. Then the duplicates come back, which means the question was never the merge.
Matching is the question. Email address is the only key that is genuinely unique, and it changes the week somebody leaves a company and carries on filling in forms from a personal address. Company name is the key everyone reaches for and it is the worst one available: Acme, Acme Inc, Acme Inc., Acme Incorporated and ACME all arrive within a quarter, and one of them has a trailing space. Email domain is better and breaks on anyone using Gmail, on subsidiaries that share a parent domain, and on the holding company whose three brands all sit behind one.
Pick your matching key deliberately, in writing, per object. Then decide where matching happens. Blocking a duplicate at the point of entry is cheap and annoys three people a month. Merging in batch is invisible and expensive, because by then an SDR has logged a week of Salesloft touches against the copy that is about to be deleted, and that activity either migrates or evaporates depending on settings nobody has looked at since implementation. Tools like LeanData exist to make routing and matching explicit rather than emergent. Even so, the rule they enforce is a rule somebody has to choose.
Four spellings of one industry
Picklist drift starts as a favour. A rep needs a value that is not there, asks the admin on a Thursday, and gets it by Friday. Nothing wrong with that transaction except that the old value stays live, the reports built on the old value keep running, and the pipeline for that segment now arrives in two pieces.
Look at any industry or lead-source picklist that has been in production for three years and you find the archaeology. Historic values nobody retired. Values that differ by a hyphen. Values that mean the same thing in two regions and different things in two business units. Values created for one campaign in 2023.
The fix is procedural. One person approves new picklist values. Adding a value requires saying what existing value it is not, and what happens to the records sitting on the thing it replaces. Deactivate rather than delete, so historic reporting survives, and keep a short list of retired values somewhere your next admin will actually read it.
Free text in a field that needed a picklist
The classic version is a field called something like Lead Source Detail, created with good intentions, which now holds webinar, Webinar, webinar - Q3, LinkedIn ad, li_ad, and about four hundred unique strings that appear once each. Nobody can group it. Nobody can report on it. It gets excluded from the dashboard and lives on forever because deleting a field feels risky.
The reverse failure is quieter and more common than the first one. A picklist too narrow for reality pushes a rep into choosing whatever sits at the top of the list, because the deal has to move and the real answer is not in there. Now the field is populated, passes validation, and is wrong, which is worse than blank. A confident number, wrong at source. Blank is honest.
If you are going to report on a field, give it a constrained set that covers the real cases plus a genuine other, then count what lands on other. Heavy use of other is the signal that the list is missing something real, and it is the cheapest research you will do that quarter.
The enrichment job that undoes last night's correction
Here is the pattern that burns goodwill fastest. An account executive notices a record says the company is in Ohio when the contract was signed in Dublin, fixes it, and moves on. The nightly enrichment run from a provider like ZoomInfo or Clay writes the old value back. Next week they notice again, fix it again, and then stop fixing anything.
Write precedence has to be explicit per field, and it is the conversation that gets skipped at implementation because nothing is broken yet. Decide which fields the enrichment provider owns outright, which fields a human owns outright, and which fields the provider is allowed to fill only when empty. That last category is where the sensible answer sits for firmographics. A checkbox marking a record as manually verified, checked by the integration before it writes, costs an hour in Salesforce Flow or Operations Hub and ends the argument permanently.
I have never seen a team regret making that explicit. I have seen one discover that nobody had chosen at all, and that the integration user (which has no idea what a human decided at four in the afternoon) had been winning by default for two years.
Field-level history is the only witness you have
When a number in the pipeline report moves and nobody knows why, history tracking is the difference between an answer and a theory. There is a cap on the number of fields you can track per object, so the choice has to be made on purpose: stage, amount, close date, owner, and the two or three fields the forecast is built on. Pick them before anyone needs them, because history only records changes made after the setting was switched on.
Teams that treat Salesforce CRM architecture as a design discipline rather than a request queue decide this at the start, alongside the sync direction and the conversion mapping. Everyone else turns it on in the week after a bad board meeting, and then discovers there is no record of the three months they actually wanted to look at.
Validation rules the reps route around
A required field at the wrong moment produces garbage at speed. Make annual revenue mandatory at lead creation and the instance fills with 1, 0, 100 and 999999999. Make it mandatory at the stage where a deal becomes a commit and the number is roughly right, because by then somebody has actually asked.
That is the whole principle. Put the rule where the information exists, not where the record begins. Required at creation, optional at creation and required at the gate: the two settings look similar in the admin screen and produce completely different data six months later. And watch the escape hatches: the moment a rep learns that typing a full stop satisfies a text validation, that becomes the house style and the field is finished as a reporting asset.
Somebody has to own each field
The "we need a new tool" conversation is a "nobody owns this object" conversation wearing a budget request. Before a field gets created, four questions deserve an answer you can point at a year later:
- Which system writes to it, and which systems read it without writing.
- What it means, in one sentence an account executive would accept without arguing.
- What a record with no value for it means, and whether that is allowed.
- Who approves a new value and who retires an old one.
Nobody running revenue operations systems well has cleaner people than everyone else. They have fewer writers per field and a written answer to those four questions, which means a record that passes through five pairs of hands arrives at the opportunity stage carrying the same facts it started with.
Data quality stops being a project at that point. It becomes a property of the handoffs, and the handoffs are the part you can design.




