A paying customer that read as having no contract
The report was that a contract expiry date had stopped copying from the deal to the company. That was true. It was also the less important half of the problem.
Client anonymised — a managed IT services provider, delivered under another company. Company names, record identifiers and staff names are withheld or changed. Every figure below is real.
- Won deals audited
- 23 closed-won deals cross-checked
- Propagating correctly
- 17 of 23 correct
- Customers affected
- 6 customers, reduced to 4
- Records changed
- 2 — both previously empty
What was reported, and what was actually happening
An account manager noticed that a contract expiry date sitting on a won deal had not appeared on the matching company record, and said so. The record had been modified about ninety seconds before the email — she was looking straight at it.
The investigation was deliberately read-only. Every closed-won deal since June carrying a contract expiry date was cross-checked against its associated company: 23 deals, of which 17 had propagated correctly, 2 were missing entirely and 4 disagreed with the company record.
That is a useful result on its own. The more useful one was the symptom nobody had mentioned.
The second symptom, which mattered more
A maintenance workflow derives an "active agreement" flag from the company-level expiry date. Because the date was blank, the flag had been set to false.
So a paying customer under a live contract was reading, in the CRM, as a customer with no agreement at all. That flag feeds renewals, churn reporting and the at-risk register. Nobody had reported it because nothing looked broken — the flag was doing exactly what it was designed to do, using an input that had silently gone missing.
This is the shape of most real data-integrity problems. The visible symptom is a blank field, which is annoying. The invisible one is everything downstream that treats the blank as meaningful.
Ruling things out before changing anything
Two plausible causes were eliminated with evidence rather than assumption. A duplicate-record hypothesis was ruled out by confirming the older identifier now redirects to the surviving record — those had already been merged. A missing association was ruled out by confirming the relevant association type was present on every single failure.
An earlier fix was also confirmed to be working: three customers whose deals had been touched in the days before all propagated correctly. That mattered, because it meant the remaining failures were a backlog to clear rather than an ongoing leak to plug — a completely different piece of work.
The six affected customers split cleanly into two groups. Two had the date sitting on a won deal, so it could be copied. Four had no date anywhere in the system, which no automation can recover — those need a person and the signed contract.
Fixing only what could be fixed safely
Two company records were backfilled from their own won deals. Both fields were empty beforehand, so nothing was overwritten, and the before-state was recorded anyway. The derived flag flipped to true on both within seconds, which was the wanted consequence and was verified by reading the records back rather than trusting the write response.
Three mismatches were deliberately left alone. Where a deal and a company disagree, the CRM cannot tell you which one is true — only the signed contract can. Overwriting blind would have replaced a visible disagreement with an invisible wrong answer.
One of those three is worth describing, because it is the most dangerous record in the set: a company date years earlier than its deal date. It is not blank. It looks populated, so nobody reviewing the record would flag it, the renewal will fire against the wrong year, and the derived flag reads false while the customer is plainly active. A stale value is harder to catch than a missing one, and worse.
The rule that came out of it
The derived flag is reliably produced from the expiry date within seconds — confirmed by observation, not assumed. So it should never be set by hand. If it reads false on a live customer, the date is the thing to fix, and writing the flag directly would mask the actual fault.
One more trap worth recording: the expiry property exists with an identical internal name on both the deal and the company. Any script or workflow touching it has to be explicit about which object it means, because the wrong one will be accepted without complaint.
The only thing that proves this is genuinely fixed is watching the next contract close end to end. Until that happens, nobody should assume it cannot recur — and that was said plainly to the client rather than declaring victory on a backfill.
Status
Backfill complete and verified; affected customers reduced from six to four. The four remaining have no date anywhere in the system and are folded into an existing contract audit with the client. Three deal-versus-company mismatches are held for a human decision against the signed contracts.
The field somebody noticed is rarely the problem. What matters is everything downstream that has been quietly treating the gap as a fact.
RevOps Diagnostic Audit