
TL;DR
- A renewal payment was accepted, but the next Salesforce invoice never generated because the date field driving the renewal countdown was not being updated.
- The failure traced back to a hidden dependency: Days_Until_Renewal__c relied on Renewed_Thru__c, but no flow or trigger was advancing that field after payment.
- The fix was one field assignment, but finding it required auditing flows, formulas, triggers, and financial-entry logic — the kind of forensic work that quietly drains ops capacity.
———
Someone paid. The system accepted it. Everyone moved on. But three months later, no renewal invoice appeared — and tracing it back meant opening flows, chasing formula logic, and eventually landing on a date field no one had touched in months.
That afternoon belongs to every ops team running on a lean bench.
The Afternoon Nobody Budgets For
The question started simply enough: why did this renewal not fire?
Not why did the customer fail to pay. Not why did the invoice fail to process. Not why did the member lapse in the real world.
The payment had landed. The business event had happened. The member had renewed.
But inside Salesforce, the renewal machine had ghosted.
No next invoice. No obvious error. No broken integration. No screaming red banner pointing to the missing step. Just a member who should have entered the next renewal cycle and an org that had not moved them there.
That is the kind of question that looks small from the outside and immediately becomes expensive once it lands on an admin’s desk.
Because now the job is not “fix the renewal.”
The job is to reconstruct how renewals are supposed to work in the first place.
Which automation listens for the payment? Which field tells the org the member has been renewed? Which formula determines when the next invoice should be created? Which trigger fires the clone? Which date is the source of truth? Which date is historical? Which date is manually maintained because that was “good enough” three years ago?
The answer was not hiding in one place. It was spread across a formula field, a cloning trigger, a payment flow, a financial-entry flow, and two date fields whose names implied more certainty than the org actually had.
And until someone traced the whole chain, the renewal was not a billing issue.
It was a context issue.
What the Org Actually Expects
The renewal logic depended on a simple countdown.
A formula field, Days_Until_Renewal__c, counts the number of days from today to Renewed_Thru__c on the Account. When that number reaches the renewal threshold, the next invoice gets cloned.
The key condition was exact: the renewal invoice cloning trigger fires when Days_Until_Renewal__c hits 90 days.
That is the entire gate.
Not “around 90.” Not “less than or equal to 90.” Not “when a payment is received.” The cloning automation waits for the countdown to land on the expected value.
So the whole system depends on one assumption: Renewed_Thru__c must be current.
If a member pays for another year, Renewed_Thru__c needs to advance. If it does, the clock resets. The formula starts counting down again. Eventually, when the account is 90 days from the next renewal date, the trigger fires and the next invoice is created.
But if Renewed_Thru__c does not move, the system has nothing new to count down to.
The payment can be real. The member can be active. The invoice can be paid in full. The team can move on.
But the formula is still looking at the old date.
And because the old date has already passed through the 90-day window, the counter never reaches that trigger condition again. The cloning trigger sits idle indefinitely, doing exactly what it was built to do — waiting for a condition the org will never satisfy.
That is the cruel part of failures like this. Nothing is obviously broken.
The automation is not malfunctioning. The formula is not wrong. The trigger is not necessarily misconfigured. The system is behaving according to the context it has.
The problem is that the context stopped being updated.
Nobody Is Writing to That Field
Once the dependency became clear, the next question was obvious: who updates Renewed_Thru__c?
That should have been the easy part.
It was not.
The field was referenced in only one flow: Invoice & Payment Financial Entries for membership.
But that flow was not maintaining the renewal date. It was reading Renewed_Thru__c to calculate general ledger entry dates. In other words, it treated the value as an input, not an output.
It used the field to derive membership timing, including a start date calculation built from:
ADDMONTHS(Renewed_Thru__c, -12) + 1
That matters because the impact was larger than a missing future invoice. If Renewed_Thru__c stayed stale, the downstream financial-entry logic could be working from stale membership dates too. The renewal trigger was the visible symptom. The GL spread calculation was another dependency hanging off the same field.
Then there was the companion field: Paid_Thru__c.
That field sounded like it should matter. It sounded like it might be the source of truth for how far a member had paid. It sounded like the kind of field that might feed renewal logic somewhere else.
But it had zero references anywhere.
No flows. No triggers. No automation. No visible dependency.
Both Renewed_Thru__c and Paid_Thru__c were effectively manually maintained.
That left one especially important flow: Invoice_Update_Account_upon_Membership_Payment.
This flow already fired when a membership payment came in. It already updated the Account. It already stamped Renewal_Membership_Payment_Date__c.
In other words, the org already had the right moment.
A renewal invoice was paid. The payment flow ran. The Account was updated with the renewal payment date.
But the flow did not also advance Renewed_Thru__c.
That was the missing assignment.
The automation knew the payment happened. It just never updated the date that told the rest of the renewal system what that payment meant.
What It Takes to Find This by Hand
This is where routine work becomes forensic work.
To confirm the gap manually, someone has to do more than search for a field name and call it done.
They need to open every relevant flow and check whether it writes to Renewed_Thru__c or Paid_Thru__c. Not just whether the fields are mentioned. Whether they are assigned. Whether they are updated on Account. Whether the update happens only under certain payment conditions.
They need to inspect Apex triggers for Account field assignments, because the renewal invoice cloning logic may not live where the payment logic lives.
They need to trace Days_Until_Renewal__c back to its source field and confirm that the formula is counting against Renewed_Thru__c.
They need to verify that Invoice_Update_Account_upon_Membership_Payment fires under the right conditions for a paid renewal invoice.
They need to confirm that the flow stamps Renewal_Membership_Payment_Date__c, proving the org has a reliable automation moment where the renewal state could be advanced.
They need to open Invoice & Payment Financial Entries for membership and understand that it reads Renewed_Thru__c for GL date logic, including the ADDMONTHS(Renewed_Thru__c, -12) + 1 membership start date calculation.
They need to check whether Paid_Thru__c was ever populated historically, because an unused-looking field may still carry business meaning, especially in older orgs where process changed faster than documentation.
They need to rule out older automation too: workflow rules, Process Builder, legacy update logic, or anything else that might predate the current flow architecture.
Each step is legitimate. None of it is busywork. A good admin should be careful before changing renewal logic tied to payments and financial entries.
But together, those steps become a half-day investigation for someone who did not build the org.
And even after doing the work, there is still the uncomfortable possibility that something was missed. A retired Process Builder. A workflow rule with one active branch. A trigger that only fires under a narrow condition. A field update buried inside an older automation pattern.
That is the cost hidden inside “can you check why this renewal did not fire?”
Not the fix.
The discovery.
The Fix Is One Field Assignment — Once You Know Where to Put It
The actual remediation is small.
Add one field assignment to Invoice_Update_Account_upon_Membership_Payment.
When a renewal invoice is paid in full, set:
Renewed_Thru__c = ADDMONTHS(Renewed_Thru__c, 12)
That single assignment advances the Account’s renewal-through date by one year. Once the field is current, Days_Until_Renewal__c has a future date to count down to again. When the Account reaches 90 days before the next renewal, the invoice cloning trigger can fire as intended.
The machine starts moving again.
If installment tracking matters, Paid_Thru__c can be handled in the same flow element. For a simple paid-in-full renewal, it may receive the same value as Renewed_Thru__c. For partial payments or installment schedules, it may need its own logic.
But the core issue remains the same: the org already had the payment event. It already had the flow. It already had the date field the renewal engine depended on.
It was missing the one assignment that connected them.
That is why these issues feel so disproportionate. The change itself takes minutes. Finding the safe place to make it takes hours.
And that is before testing, before deployment, before confirming that the GL date logic still behaves correctly, before deciding whether old Accounts need a backfill, and before documenting why this field now advances automatically.
The work is not hard because the code is complex.
It is hard because the meaning is distributed.
The Capacity Question
A team should not have to become forensic investigators every time someone asks whether a field is being written to.
That is the bigger lesson inside the renewal that never fired.
A lean ops team can absorb one afternoon like this. Every team has the occasional mystery. But these questions do not arrive one at a time forever. They pile up: why did this renewal fail, why did this routing rule miss, why did this approval block, why did this report change, why did this automation run twice, why did this field stop moving?
Each one pulls skilled people off roadmap work and into reconstruction.
Sweep helps teams avoid that tradeoff by giving AI agents the org context before they act. The audit in this story — every flow, trigger, formula, assignment, dependency, and missing write — should not require a crisis. It should run continuously, surfacing gaps like this as questions before they become customer-facing failures.
Because the capacity problem is not that ops teams lack talent.
It is that too much of their talent gets spent rediscovering how the system works.
The renewal did not fail because nobody cared.
It failed because the org depended on a field that everyone assumed was being maintained.
And in complex systems, assumptions are where the afternoons go.


