Google caps every GA4 parameter value at 100 characters. A typical product page URL, with a collection path, a handle, and a couple of tracking query params still attached, clears that limit easily. Push the full URL into a custom parameter instead of page_path and GA4 does not reject it. It quietly cuts the string at character 100 and stores the fragment, per Google's own configuration limits documentation. Nothing errors. The hit arrives. Every report built on that parameter is matching against a truncated value nobody chose.
That is the gap most "GA4 audit" checklists do not cover. They check whether GTM's tags and triggers are wired correctly, whether purchase fires once instead of twice, whether consent mode blocks the right tags. All of that matters. None of it is a GA4 dataLayer audit, the specific check of whether the dataLayer object those tags depend on actually matches the event schema GA4 expects, parameter by parameter.
- A GTM container audit checks the tags. A dataLayer audit checks the data those tags are reading, before GTM ever touches it.
- Three defects account for most of the damage: a missing ecommerce reset between events, a recommended event missing its required parameters, and values that silently get cut off past GA4's length limits.
- None of these three show an error anywhere in GA4's interface. The hit still arrives. The data inside it is wrong.
Why a GTM audit and a dataLayer audit catch different bugs
We've written before about GTM container audits: the nine-part checklist for orphaned triggers, duplicate tags, and consent gaps inside the container itself. That checklist assumes the dataLayer feeding the container is already correct, and checks whether GTM is reading it faithfully.
A dataLayer audit starts one step earlier. It treats the dataLayer as a contract between the site's frontend code and everything downstream of it: GTM, GA4, Google Ads, Meta, any tool reading that same object.
If the contract itself is broken, a perfectly configured GTM container just faithfully forwards bad data at scale. Fixing the container doesn't fix a malformed items array. Only checking the dataLayer itself does.
Google's own guidance on GA4's ecommerce event sequence defines the chain a dataLayer is actually supposed to produce: view_item_list, view_item, add_to_cart, begin_checkout, add_shipping_info, add_payment_info, purchase. A dataLayer audit's first job is confirming every one of those events actually exists in the code, carries the right parameters, and fires at the point in the funnel its name implies, not just that GTM has a trigger waiting for it.
The five dataLayer defects that break ecommerce reporting without an error
1. The ecommerce object never resets between events
GA4's ecommerce guidance is explicit that ecommerce: null needs to be pushed immediately before each new ecommerce event, clearing whatever the previous push left behind. GTM merges dataLayer pushes rather than replacing them, so skipping that reset lets item-array data from one event bleed into the next. A view_item_list push that never clears can leave stale items sitting in the object.
The following add_to_cart then picks up a blend of old and new items. The tag still fires. GA4 still logs a hit. The product data inside it is wrong, and nothing in the interface flags it.
2. A recommended event is missing the parameters that make it recommended
GA4 ships a defined list of recommended events, each with required parameters attached to the name. Push generate_lead without currency and value, or purchase without transaction_id, and GA4 doesn't reject the hit.
The event keeps its familiar name in reports, but it stops behaving like a recommended event. Automatic insights, benchmark comparisons, and machine-learning features Google ties to that specific event and parameter set no longer apply to it, and nothing in the interface warns that it happened.
3. Names and values get truncated past GA4's limits
GA4 caps event and parameter names at 40 characters and parameter values at 100 characters, per Google's own configuration limits documentation. A full page URL pushed as a parameter value routinely exceeds that 100-character cap and gets silently cut, which is exactly why page_path exists instead of pushing the full URL.
A dataLayer audit checks every custom parameter against both limits, because a truncated value doesn't throw an error either. It just arrives shorter than intended, and anything downstream matching on that value starts failing to match.
4. The items array is inconsistent across the funnel
GA4's ecommerce reports depend on the same product appearing with the same item_id, consistent casing, and a stable set of fields at every step from view_item through purchase. A common defect: the items array on view_item carries item_id as a string, while add_to_cart further down the funnel, built by a different developer or a different app, sends it as a number, or spells item_category differently.
GA4 treats these as different items, and funnel reports quietly fragment a single product's journey into two.
5. Variable naming drifts between the dataLayer and the GTM variables reading it
GTM's dataLayer variables are case-sensitive. A dataLayer that pushes userId in one template and user_id in another produces two GTM variables that each only catch half the traffic, silently, with no warning that the other half exists.
This is the specific defect a GTM container audit is least likely to surface on its own, since the container's variables look correctly configured. The mismatch only shows up when the dataLayer's actual key names are checked against what GTM is listening for.
How to check your own dataLayer this week
Open the browser console on your own site and walk the funnel: a category page, a product page, add to cart, checkout, and a completed purchase if you can do it safely in a test environment. At each step, type dataLayer into the console and inspect the last pushed object. Confirm the ecommerce key resets before the next event, confirm currency and value are present on every event that requires them, and confirm item_id keeps the same type and casing across every step.
Cross-check that against GTM's own Preview mode and GA4's DebugView side by side. Preview mode shows what GTM received; DebugView shows what GA4 logged as a result. A discrepancy between the two, an event that shows correctly in Preview but arrives malformed or incomplete in DebugView, usually means the dataLayer itself pushed something GTM's variables weren't built to parse, which is the exact failure mode a tags-only review misses.
This is the same schema-first check a fixed-price tracking audit runs before anything else, and a sample of what that report actually documents is available to look through at the tracking audit sample report.
When the dataLayer schema needs a rebuild, not just an audit
Some defects are a quick code fix: adding a missing reset, correcting a parameter name, standardizing casing across two apps that both write to the dataLayer. Others, most often a dataLayer that was never built around GA4's recommended event schema to begin with, a store running three different apps that each push their own version of the same event, are a sign the dataLayer needs rebuilding from the funnel out, not patching event by event. That is the point where a tracking setup rebuild that defines one dataLayer contract for the whole funnel pays for itself faster than another round of individual fixes.
What to check before you call it done
- Does every ecommerce event push
ecommerce: nullimmediately before the next event's data. - Does every recommended event carry the specific parameters GA4 requires to stay a recommended event, not a silently downgraded custom one.
- Does any parameter value risk truncation past GA4's 40-character name and 100-character value limits.
- Does
item_idand every other shared field keep identical type and casing fromview_itemthroughpurchase. - Do the dataLayer's actual key names match, case for case, what GTM's variables are listening for.
A GTM container audit tells you the tags are wired correctly. None of the five checks above are things that audit catches, because they live one layer below it, in the object the tags were built to trust.

