The Little Things We Don’t Do Are Often the Things That Break
So i was added to a massive chain email that felt like it went to the depths of marketing hell, the first few reponses were “i think we should add Brad to this” and “yeh, he will find it”.
Scrolling down the endless email trying to decipher what the hell im actually looking at it was a back and forth by a bunch of non technical people trying to find a tech problem.
Google Ads was counting ghost conversions.
Google was reporting that people were converting, but the actual number of leads in salesforce didn’t match. Somewhere between the landing page and Google Ads, the maths was not mathing.
What followed was an Alice in Blunderland journey through the entire setup.
I checked Unbounce. I checked Google Tag Manager. I checked Google Ads. I reviewed the triggers, tags, form behaviour, conversion events and filtered labels in network panel. I turned over every stone, looking for the complicated technical issue that must have been hiding underneath.
Because that’s what we tend to do.
When a problem involves several platforms, custom code and conversion tracking, we automatically assume the explanation must be equally technical. We start looking for broken integrations, duplicate tags, browser privacy restrictions, consent issues, attribution problems or some strange race condition. If you went and dumped a prompt in your favorite flavour of LLM you would get the same tech debugging at the deepest level
But sometimes the problem really is that technical.
This time, it wasn’t.
The form worked—but it didn’t work perfectly
The landing page included a custom validation script designed to stop people from submitting the form with a personal email address.
If somebody entered a Gmail, Yahoo or another personal address, the page displayed an error. From the visitor’s perspective, the form appeared to be working correctly.
But underneath that visible experience, the form was using the submit action to validate.
The validation script showed the error, but it didn’t fully interrupt the submission process. That meant the event being used as the Google Ads conversion trigger still fired.
To the visitor, the form said:
Please use a company email address.
But to Google Ads, the page said:
Its been submitted, we have a new conversion.
Google Ads wasn’t creating imaginary data or randomly inflating the numbers. It was doing exactly what it had been told to do.
The real problem was that we had defined a conversion as an attempted form submission, rather than a successfully completed one.
That small distinction created the ghost conversions.
And the fix was relatively simple.
We could make the validation part of the form’s submission logic, ensuring that a rejected entry could never generate a submission event. Alternatively, we could move the conversion trigger to something that only happened after a genuinely successful submission, such as the loading of a dedicated thank-you page.
Hours of investigation including watching recordings of every single visit eventually led back to a tiny gap in the original implementation.
“It works” is a dangerously low standard
Here is the uncomfortable part: the form had been tested before it launched.
It was filled out.
We submitted it.
The information passed through.
Technically, it functioned.
Was it perfect?
Hell no.
And that is the important difference.
We often treat launch testing as a simple question:
Does it work?
But that question doesn’t go far enough.
If a valid form submission reaches the CRM, we say the form works. If the conversion appears in Google Ads, we say the tracking works. If the error message appears when somebody enters a personal email address, we say the validation works.
Each individual component appears to pass its own test.
What we don’t always test properly is whether they work together from beginning to end.
We assume that because the validation displays an error, it must have stopped the form.
We assume that because Google Ads records a conversion, a genuine lead must exist.
We assume that because the data reaches the CRM, every trigger that fired along the way must also have been correct.
Those assumptions are where the problems begin.
A system can be technically functional while still being operationally wrong.
That is exactly what happened here. The form worked. The validation worked visually. The tag worked. Google Ads worked.
Every individual piece did something close to what it was supposed to do.
But the complete journey was broken.
The gaps between tools are where problems hide
The hardest problems often don’t exist inside one platform.
They exist in the handoffs between platforms.
Unbounce has its own idea of what counts as a submission. The custom validation script has its own logic for deciding whether an email address is acceptable. Google Tag Manager listens for a particular event. Google Ads records that event as a conversion.
Each tool only knows what it has been told.
Google Ads doesn’t know whether the person saw an error message.
Google Tag Manager doesn’t know whether the submitted email address meets the business requirements.
The validation script doesn’t care what marketing tags are listening in the background unless somebody explicitly connects those pieces of logic.
We see one customer journey.
The technology sees a sequence of separate events.
That is why end-to-end launch debugging matters.
You cannot test each component in isolation and assume the complete system will behave correctly. You have to follow the signal all the way through.
- What did the user see?
- What did the browser do?
- What event entered the data layer?
- Which tags fired?
- What did the advertising platform record?
- Did a lead appear in the CRM?
- Did the CRM accept or reject it?
And, most importantly, did every system agree about whether the outcome represented success?
If one platform says “error” while another says “conversion,” the setup isn’t working—regardless of whether the individual tests technically passed.
We usually test the happy path
Most launch testing focuses on the happy path.
Enter valid information.
Click submit.
See the thank-you message.
Check that the lead arrived.
Confirm that the conversion appeared.
Job done.
But customers don’t only follow the happy path.
They enter personal email addresses. They miss required fields. They use unusual characters. They click twice. They go backwards. They refresh pages. They reject cookies. They submit from slow connections. They trigger errors that nobody expected.
Robust launch debugging has to test both success and failure.
What happens when the email address is rejected?
Does the form genuinely stop, or does it only display an error?
Does a rejected attempt still enter the data layer?
Does Google Tag Manager fire anything?
Does Google Ads record a conversion?
Does a partial or invalid lead reach the CRM?
Can the user correct the error and submit again?
If they do, does the system record one conversion or two?
The negative paths are not obscure edge cases. They are part of the product.
An error message is not proof that an action stopped. A thank-you message is not proof that data arrived. A conversion event is not proof that a business outcome occurred.
Every important state needs to be verified, not assumed.
The hours we “save” at launch come back later
Launches are rarely relaxed.
There is normally a deadline, a list of last-minute changes and pressure to get the campaign live. Once the main journey appears to work, it is tempting to stop testing and move on.
That saves a little time today.
Then, weeks or months later, the numbers stop making sense.
The advertising platform reports more conversions than the CRM contains. Cost per lead looks better than it really is. Campaign optimisation begins learning from false signals. Budgets are moved towards ads that appear to perform well but may only be generating invalid submission attempts.
Now the problem is no longer confined to the form.
It has contaminated reporting, decision-making and potentially the optimisation of the campaigns themselves.
Somebody then has to retrace the entire journey without knowing where the failure started.
Was it the landing page?
Was it the validation?
Was it the tag?
Was it Google Ads?
Was it consent mode?
Was it attribution?
Was it the CRM integration?
A few extra checks at launch can prevent hours of forensic debugging later—usually when the pressure is higher and the consequences are more significant.
This is the strange economics of quality assurance.
The extra hour before launch feels expensive because everyone is waiting.
The ten hours spent investigating bad data three months later somehow feel unavoidable.
They aren’t.
Launch debugging is not about chasing theoretical perfection
When I talk about making a launch perfect, I don’t mean endlessly delaying it while we test every imaginable possibility.
Perfect does not mean eliminating all uncertainty.
It means being exact about the outcomes that matter.
If we say a conversion represents a successful lead, then we should prove that only successful leads can trigger it.
If we say invalid email addresses are blocked, then we should prove that they are blocked at every relevant layer—not merely that an error message appears.
If advertising decisions will be based on the data, then we should prove that the data describes what we think it describes.
That requires more than checking whether something happens.
It requires checking:
- what happens;
- when it happens;
- why it happens;
- what does not happen;
- and whether every connected system interprets the outcome in the same way.
The goal is not perfection for its own sake.
The goal is confidence.
When the campaign launches, we should know what every important event means. We shouldn’t be relying on assumptions that only become visible when the numbers break.
Test the meaning, not just the mechanism
The biggest lesson from the ghost conversions is not that custom validation scripts are unreliable or that conversion triggers should always use thank-you pages.
The lesson is that technical events do not automatically represent business outcomes.
A form_submit event might mean somebody successfully became a lead.
It might also mean somebody clicked the submit button, failed validation and never sent usable information.
Those are completely different outcomes, but a tracking platform cannot understand that difference unless we build it into the implementation.
So when debugging a launch, don’t only ask:
Did the tag fire?
Ask:
Should the tag have fired?
Don’t only ask:
Did the form submit?
Ask:
Did the business receive a valid lead?
Don’t only ask:
Did Google Ads record a conversion?
Ask:
Did something happen that we genuinely want Google Ads to optimise towards?
Mechanisms tell us that the technology did something.
Meaning tells us whether it did the right thing.
The little things are often the big things
It is easy to dismiss launch debugging as a final checklist item.
Fill in the form. Check the CRM. Confirm the tag. Move on.
But the little things we don’t check are often the things that eventually break the whole picture.
One validation script that doesn’t fully stop a submission.
One trigger attached to an attempt instead of a success.
One assumption that every platform shares the same definition of a conversion.
None of these things looks dramatic at launch.
Then the data starts lying.
The campaign begins optimising towards the wrong behaviour. Reports become less trustworthy. Teams spend hours investigating increasingly technical explanations for a problem that began with one small, untested handoff.
That is why robust launch debugging matters.
Not because every launch needs to be delayed until the system is theoretically flawless, but because “technically working” is not the same as working properly.
Follow the entire journey.
Test the happy path and the failure paths.
Check what the customer sees, what the browser records, what the tags send and what the business receives.
Make sure every system agrees about what success means.
Because spending an extra hour finding the small things before launch is almost always cheaper than spending ten hours finding them after everything fucks up.
Brad Holmes
Web developer, designer and digital strategist.
Brad Holmes is a full-stack developer and designer based in the UK with over 20 years’ experience building websites and web apps. He’s worked with agencies, product teams, and clients directly to deliver everything from brand sites to complex systems—always with a focus on UX that makes sense, architecture that scales, and content strategies that actually convert.