The dataLayer is the foundation everything else builds on.
We inspect the dataLayer object on every page — checking it's initialized before GTM/gtag loads, validating push events are well-formed, identifying multiple dataLayer declarations that overwrite each other, and verifying structural integrity (no malformed JSON, no circular references, no missing required keys).
The dataLayer is the bridge between your website's actual behavior and your analytics tags. Tags read from the dataLayer to know what happened. If the dataLayer isn't there, or is initialized after tags run, or gets overwritten by a second declaration, every tag downstream of it gets the wrong information — or none at all.
A headless commerce site built on Next.js initializes dataLayer in both _app.js AND _document.js. The client-side declaration wipes the server-side one. Every product page pushes data to a dataLayer that GTM then re-initializes — losing all the product context for tagging.
A travel booking site has dataLayer.push() calls in 50 places but never initialized dataLayer with window.dataLayer = window.dataLayer || []. On slow connections, the first few pushes happen before GTM loads — and those events are lost forever.
A WordPress site uses three plugins that each push to dataLayer. Two of them use the same parameter name (user_type) with different meanings. Whichever fires last wins — making the user_type dimension in GA4 a coin flip between two different definitions.