Deliver and maintain › Testing and Debugging
Common Issues and Solutions
The first Kestrel test cycle, on 22 May, tested twenty eight solutions. Twenty six had something wrong with them. Two were correct first time.
That is a normal first cycle and not a sign that anything has gone badly. What is more useful than the number is that the twenty six were not twenty six different problems. They were a small set of faults, repeating.
Somebody who has done this for a few years names the likely cause before opening anything, and is right most of the time. That is recognition rather than intuition, and this section is the list they are recognizing from.
Every fault in this section is a real row in the Tracker sheet, with its dates and its status. The Summary sheet holds the counts quoted above. Reading the two beside this section is the fastest way to see how a finding is written down.
The faults that keep recurring
Nobody reports a fault in useful terms. What arrives is a number somebody does not believe, which is the end of the chain. The work is translating that backward into a place to look.
| What you are told | Usually caused by | The one check that settles it |
|---|---|---|
| There is no data at all | Collection, or the report suite | Does a request appear, and which suite is in its path |
| The numbers are roughly double | Two rules firing, or a rule firing twice | Count the requests produced by one action |
| A variable is empty in reports | Anywhere, which is why it is the hard one | Is the value in the request, and is it in the data layer |
| Right in the hit, wrong in reports | Processing rules, VISTA, or a channel rule | Compare the sent hit with the post processed hit |
| Orders missing, revenue short | Purchase ID deduplication | Are two orders sharing an identifier, or is none being set |
| Page views far too low | Single page application navigation | Does a hit fire on the second screen of a journey |
| It works for me and not for them | Consent, blockers, timing, or browser | Reproduce on a slow connection and a second browser |
| Traffic dropped overnight | Bot filtering, consent changes, or a certificate | Compare against the day it started, not against today |
The same call firing more than once
This was the single most common fault in the Kestrel cycle, and it appeared in three different forms.
KES-S003, a product click on a listing page, fired the direct call twice on every click. Product clicks were exactly double. Two rules were responding to the same click.
KES-S002, the checkout screens, fired on the first load as well as on each step change, so the checkout counted one page view too many. One rule, firing in a situation nobody intended.
KES-S009, starting the checkout, fired again every time the customer went back a step. The rule was correct and the trigger was wrong.
All three are found the same way. Do the action once, then count the requests before reading any of them. If you open the first hit and start reading variables, a second identical hit is invisible.
One case that looks the same is not a fault. Multi-Suite Tagging is supposed to produce more than one request, going to different report suites. Check the suite in each path before reporting a duplicate.
A repeated purchase ID removes the whole hit
Adobe removes duplicate purchases using an identifier sent on the same hit as the purchase event. Send two hits with the same identifier and the second is treated as a repeat of the first. That is correct behavior, and it is what stops a customer refreshing a confirmation page from being counted twice.
Kestrel hit exactly that on KES-S012. On 22 May, refreshing the confirmation page sent a second purchase and revenue on the test account was double. A guard was added, and by 29 May twenty refreshes produced no duplicate.
What surprises people is how much gets removed. When a hit is treated as a duplicate purchase, all of its conversion data is dropped, not only the purchase event. The eVars on that hit, the other events on it, the products string. The request succeeded and none of it appears anywhere.
Deduplication applies across all visitors rather than within one, and identifiers are held for 37 months. So an order number series that restarts, or one that overlaps with another brand sharing the report suite, creates duplicates between two people who have never met. The opposite failure is just as quiet. When no identifier is supplied, Adobe generates one from the events and product string, keyed to that visitor, held for 24 hours, with only the last five kept. A customer who buys the same item twice in one day can lose the second order. Sending a genuinely unique order identifier on every purchase hit prevents both. It is a one line change, and it is almost never made until after the first quarter end that does not reconcile.
Values that are present and wrong
These are harder to notice than a missing value, because the report looks populated. Four Kestrel rows show the range.
KES-S005 sent the cart total as the quantity, so adding one product reported two. The value was in the right position and it was the wrong number.
KES-S010 dropped the delivery charge whenever the charge was zero, because the site treated zero as nothing to send. Free delivery orders looked like orders with no delivery data.
KES-S015 sent the search result count as a string rather than a number, so no null search was ever recorded. The value was there, in the wrong type.
KES-S016 counted search result positions from zero rather than one, so every position in every report was one place out.
The common thread is that none of these would fail any check that only asks whether a value arrived. They are caught by reading the value against the design and asking whether it is the value the design asked for.
On 22 May the Kestrel customer ID arrived as a raw email address. Testing stopped and it was raised immediately, rather than being written down and carried to the end of the cycle. That is the correct response. A hit carrying a plain email address is a privacy problem the moment it reaches Adobe, and every minute of further testing adds more of them to a report suite. Raise it, get collection stopped or the value hashed, and resume afterward. The obligations behind this are covered in Privacy and Data Retention.
Values that go missing on a slow connection
A rule reads the page at the moment it fires. If the call goes out before the site has filled its data layer objects, the call leaves with empty values and nothing records a problem. The rule fired, the request was sent, Adobe accepted it, and the report is thinner than it should be.
This is the fault from the opening of Debugging Tools Overview, and Kestrel had it twice: on the global page name, and on KES-S004 where every product view arrived empty.
It depends on timing rather than logic, so it is intermittent. On a fast connection the objects are ready first and it works. On the tester's machine it usually works. On some proportion of real visits it does not, and that proportion is invisible, because a hit with an empty variable looks like a page that genuinely had no value.
The instinct is to add a delay before the rule fires. Resist it. A delay is a guess about somebody else's network. It makes the fault rarer without removing it, and a fault that appears once a fortnight is harder to fix than one that appears every time. The repair Kestrel used was to change the rule to a direct call the site fires once its own values are set. The site knows when its data is ready and the tag manager never will.
Set the network tab to a slow profile and walk the journey again. It costs a few minutes per cycle and it is the only cheap way to find ordering faults before customers do. Everything about a developer machine is built to hide them: a fast connection, a warm cache, and a page that has been loaded fifty times already. A solution that passes at full speed and fails when throttled has not failed intermittently. It has told you what it does, and roughly what share of real visitors it does it to.
When no call fires at all
Check four things, in this order, because it is roughly the order of likelihood. The library did not load. The report suite in the request is not the one being reported on. Consent was declined or never given. A browser extension blocked the request.
Kestrel had three variants worth knowing. KES-S018 sent no call on registration at first, then sent one on failed registrations too, which is the opposite fault appearing after the fix. KES-S021 fired on header and menu links but not footer links, so the fault was in which elements the rule matched rather than in the rule itself. And KES-S013 sent nothing at all on a failed payment, because the failure page was served by the payment gateway and the site never regained control.
That last one is worth pausing on. No amount of debugging the site will find a call that cannot fire, because the page belongs to somebody else. The repair was for the gateway to return to a site page first.
Consent, blockers, and traffic you will never see
Some missing data is correct. Visitors who decline consent are not tracked, ad blockers stop requests before they leave, and bot filtering removes traffic deliberately. None of that is a defect and none of it is recoverable by debugging.
What is a defect is tracking somebody who declined. Kestrel found that on KES-S038: two rules fired before consent had been answered. That is the direction that matters, and it is worth checking explicitly rather than assuming the consent extension handles everything.
For the rest, the useful response is to know the rough size of each. Then nobody spends a week chasing a discrepancy that is working as designed, and nobody quotes a figure as though it covered everybody. An implementation reporting fewer visits than the server logs is normal. Being able to say roughly why, in a meeting, is worth more than closing the gap.
When a solution does not pass
Most of what happens in testing is neither a pass nor a failure, which is why the validation report has four statuses rather than two. The Kestrel cycle ended with one of each of the difficult three.
| Status | Kestrel example | What it needs alongside it |
|---|---|---|
| Partly passed | KES-S013, payment failure. Two reasons map correctly, three gateway timeout codes still arrive as numbers | The exact part that does not work, an owner, and a date |
| Failed | KES-S019, sign out. No call across all three cycles. The session clears and the page reloads before the tag manager sees anything | An owner and a date, never left without both |
| Ignored | KES-S023, form tracking. The form component belongs to a third party whose next release lands after go live | A reason, who agreed it, and when |
Ignored is the status that keeps the document honest. The alternative is silence: the solution stays on the list, nobody mentions it, and in October somebody builds a report on form completions and finds nothing. At that point the implementation looks unreliable, and there is no evidence on either side about whether it was ever delivered.
Kestrel finished with twenty four passed, two partly passed, one failed and one dropped, and a recommendation to proceed. That is a result somebody can act on, and it is only possible because the difficult three were written down as they happened.
Working a fault to a cause
Use this for a fault that did not yield to recognition, which is about a third of them. It is deliberately slow, because guessing has already failed by this point.
- Part one, make it testable
- Turn the complaint into a claim with a variable, a page, an action and an expected value. Until it is testable it cannot be closed either, which is how faults stay open for months.
- Find out when it started from the data, before believing anybody's account of when it started. A start date points at a release, a configuration change or a certificate. It is often the whole answer and it costs one report.
- Reproduce it. If you cannot, find out what is different about the people who can. Browser, connection speed, consent state, geography, whether they are signed in. The difference is usually the cause.
- Part two, find the stage
- Read the request and decide which half of the chain you are in. Value absent means the browser side. Value present means inside Adobe. One look retires half the possibilities.
- On the browser side, compare the data layer against the request. Two comparisons, one minute, and it names which team owns the repair without anybody arguing for it.
- On the Adobe side, compare the sent hit with the post processed hit, then check the variable is enabled in the report suite. A variable that was never enabled reports nothing however perfect the hit is, and it is the last thing anybody checks.
- Part three, close it properly
- Before fixing anything, work out how far back the fault goes and what has been reported from the affected data. The repair is usually the small half of the job. Somebody has been reporting on this for weeks and needs telling.
- Fix it, then confirm the fix through the full round trip rather than in the hit alone. A fix confirmed only in the browser repeats the assumption that produced the fault. Wait for the report.
- Add a dated line to the row with the cause and the fix, leave the earlier findings in place, and set the status. The next person to meet this fault is probably you, in eight months, having forgotten every detail of it.
That is a fault taken to a cause rather than to a workaround. Where the fault reached a report somebody presents from, add a written note of the affected period. The number people remember is the one they saw, not the one corrected later.
Where this module leaves you
With a way of working that does not depend on the tools. A value travels five stages. No tool sees all five. The request is the only fact, so start there, and two comparisons tell you which stage a fault lives in and which team owns the repair. Departure is not the same as arrival, so the round trip is the only proof that counts. And most faults are a small set that repeats, which you now have a list of.
Each of those answers goes in the same place: a row in the validation report, with a date, a status and an owner. That is what turns a week of testing into something a client can sign, and it is the subject of Validation and Sign-off.
Very little of this belongs to Adobe Analytics. The tools change often. The bookmarklet everybody used ten years ago is unmaintained, the interface that carried reporting for fifteen years stopped working in 2024, and the debugger gained a new capability in 2026. What holds is the chain, the boundary in the middle of it, and the discipline of writing down what you saw on the day you saw it.
Customer Journey Analytics moves that boundary. Its processing decisions happen when you run a report, rather than when the data arrives. That changes what can be fixed later and what has to be right first. What Is Customer Journey Analytics covers that model and what it changes.
Most of the fixes here are made on three screens rather than in the browser. Processing rules and bot rules sit under Admin > Report Suites > Edit Settings > General. Whether a variable is enabled, and how it persists, sits under Edit Settings > Conversion > Conversion Variables. Whether an event deduplicates on an identifier sits under Edit Settings > Conversion > Success Events. VISTA rules appear on none of these, because Adobe configures them, which is worth knowing before spending an afternoon looking.
This article focuses on the concepts, architecture, and practical guidance behind the topic. For the latest UI walkthroughs and step-by-step implementation instructions, use the links below. They leave this site and open Adobe's own documentation in a new tab.