Skip to main content

Container Audit: Automated GTM Checks and What They Prove

What Container Audit in AI Tag Manager checks in a GTM workspace, how findings are graded by severity and confidence, and where the manual audit still has to take over.

A GTM container that has been live for a couple of years is rarely broken in one obvious place. It is broken in twelve small ones: a conversion tag somebody paused during a test and forgot, a GA4 event tag pointing at a measurement ID variable no Google tag declares, a Meta pixel pasted in as Custom HTML with consent status still "not set", three triggers nothing fires on. None throw an error. Each quietly removes a slice of the data you thought you had.

Finding them by hand means opening every tag, trigger and variable and cross-referencing by eye. The ninety-minute measurement audit playbook describes how to do that on a schedule. Container Audit in AI Tag Manager is the automated counterpart: it reads a workspace through the GTM API, runs a fixed set of configuration checks, grades what it finds, and offers a Fix button on the subset it can safely repair. This post covers what it checks, how findings are graded, and where the manual audit still has to take over.

What Container Audit reads before it checks anything

The tool works on a single GTM workspace, not a published version. You pick an Account, a Container and a Workspace; the pickers use the OAuth grant you gave at sign-in, so there is nothing to export or upload.

When you press Run audit, the edge function lists the workspace's tags, triggers, variables, folders and enabled built-in variables and builds a snapshot in memory. The summary line says what was read, for example "Read 48 tags, 61 triggers, 39 variables, 4 folders and 22 built-in variables." Every check runs against that snapshot, so the audit describes the draft workspace as it sits right now, not what is firing on your site.

One honest detail: the server follows at most ten pages of any list. If a container is large enough to exceed that, the result carries a truncated flag and the page puts an amber box above the count: "This audit is incomplete." A clean result on a truncated audit means "nothing found in what was read", not "nothing to find".

The five severity rungs and what each one means

Every finding lands on one of five rungs: Critical, High, Medium, Low and Info. A few checks move between rungs depending on context. A paused tag is Low, but a paused Ads conversion tag or Google tag is High because that is a tracking gap nobody notices. An ungated advertising pixel is High, and Critical when the site serves a region where Consent Mode v2 is a legal matter.

SeverityTypical findings
CriticalAd pixel in Custom HTML firing with no consent gate on a regulated-region site
HighTag with no firing trigger, broken trigger reference, GA4 event with no measurement ID or event name, more than one GA4 configuration tag, consent-relevant tag with consent status not set, paused conversion or config tag
MediumUniversal Analytics tag still present, document.write in Custom HTML, Custom JavaScript variable, dangling {{variable}} reference, variable with missing config (no dataLayer key, no cookie name, no lookup rows), GA4 event duplicating Enhanced Measurement, multiple measurement IDs
LowUnused trigger, unused variable, All Pages trigger with no conditions, unrecognised tag type, placeholder or whitespace-padded names, ordinary paused tag
InfoCustom HTML present (review for PII), empty folder, commonly used built-in variable not enabled, Custom HTML that might be an ad pixel

The severity chips above the table double as filters. Turn every chip off and the page resets them rather than showing an empty list, because an empty list reads as a clean container.

Confidence is graded separately from severity

This is what most distinguishes the tool from a checklist. Every finding has a Confidence label, with a tooltip explaining it:

Splitting confidence from severity lets a High finding marked "Needs a live check" sit in the list without pretending to be proof, and stops someone editing a client's container on the strength of a guess.

Firing and reference checks: the ones that are always right

The audit walks every tag and asks whether it has at least one firing trigger, and whether each trigger ID it references still exists. A reference to a deleted trigger is High. The engine knows GTM's reserved built-in trigger IDs (All Pages lives in the 2147479xxx range and never appears in the triggers list), so a configuration tag firing on All Pages is not falsely reported as broken.

The same walk collects {{Variable}} references from tag parameters, trigger conditions and other variables, and compares them against the variables the workspace defines plus the built-ins that are enabled. Any reference with nothing behind it is a dangling variable reference at Medium. A tag sending {{DLV - transaction_id}} after that variable was deleted never shows up in Preview mode unless you test a purchase.

GA4 and Google Ads configuration checks

For GA4 event tags the audit checks that a measurement ID is set, that an event name is set, and whether the event name is one that GA4 Enhanced Measurement already tracks (page_view, scroll, click, file_download and the rest). That last one is Medium and Likely, because the audit cannot see the web stream to know whether Enhanced Measurement is on.

At the container level it counts GA4 configuration tags and reports more than one as High ("More than one causes duplicate sessions"), and it collects every distinct measurement ID in use and reports several as Medium with the suggestion to consolidate onto one {{GA4 Measurement ID}} variable. Google tags with no tag ID and Ads conversion tags with no conversion ID are High. Universal Analytics tags are Medium under Deprecated: UA stopped collecting on 1 July 2023 and now only adds page weight.

Consent Mode v2 checks and the ad pixel classifier

Two checks cover consent. The first: for consent-relevant tag types (GA4 events, the Google tag, Ads conversion and remarketing, Floodlight, Microsoft Ads, LinkedIn Insight, Hotjar and similar) the audit reads the tag's consent settings. "Needed" and a deliberate "not needed" both count as configured. Only "not set" is flagged, at High, with a recommendation naming the consent types that tag type usually requires.

The second runs Custom HTML tags through a pixel classifier that looks for the initialisation patterns of known advertising networks. If the snippet is an ad pixel, its consent settings are checked against what that network needs under Consent Mode v2. Gated but incomplete is Medium. No gate, declared as needing no consent, or requiring consent without ad_storage is High or Critical depending on region. A correctly gated pixel produces nothing. The Consent Mode v2 compliance playbook covers the policy side of why these matter.

Variables, naming and housekeeping

The variable checks catch configuration that returns undefined without complaint: a Data Layer Variable with no key, a URL variable with no query key, a cookie variable with no cookie name, a lookup table with no rows. All are Medium and Certain. Custom JavaScript variables are Medium under Security, because they run arbitrary code wherever they are referenced.

Naming checks catch placeholder names ("Untitled Tag", "Copy of ...") and names padded with whitespace, both at Low, plus duplicate names for tags and triggers. The post on GTM naming conventions at scale explains why this is worth fixing before a container grows. Housekeeping checks are Info: unused triggers, variables that nothing references, empty folders, and built-in variables that are commonly needed for GA4 and event tracking but are switched off.

How to use it, step by step

  1. Open Container Audit from the tools menu.
  2. Choose an Account, then a Container (the picker searches by name or GTM-ID), then a Workspace.
  3. Press Run audit. The button reads "Auditing" while it runs and "Run again" afterwards.
  4. Read the amber "This audit is incomplete" box first if it appears, then open the "What this audit cannot tell you" panel under the summary. It lists the six checks that need a live page.
  5. Use the severity chips, the category dropdown ("All categories", "Consent Mode", "GA4 events", "Firing" and so on) and the Search findings box to narrow the table. The line "Showing 12 of 54 findings" keeps count.
  6. Work down the What to do column. Each row carries the problem and the action together.
  7. Press Fix where it is offered, or type DELETE and press Delete for removals. A row with no button says "Needs your decision" and means it.
  8. Export with the CSV, Markdown or JSON buttons. Exports contain the filtered list, and the page warns you when that differs from the full result, so clear the filters before sending a file to someone. The file is named after the container and the run time, for example Acme-Web-20260825-1432.md.
  9. Run again after applying fixes. Applied markers are cleared on a re-run, so a green tick never sits beside a finding that has come back.

What the Fix button will and will not do

Fixability is decided on the server, per finding, by the same function that executes the fix, so you never see a button for something the server then refuses. The list is short:

Everything else is refused with a reason. Renames need a name only you can choose. A tag with no firing trigger needs a trigger chosen for it, and picking one automatically would decide when that tag fires on your site. The browser sends the finding, never a method or an API path; the server recomputes the write from it. All writes land in the draft workspace. Nothing here publishes, so you still review the diff and create the version yourself.

How it differs from a manual checklist

The manual playbook and this tool answer different questions. A manual audit is a judgement exercise: you watch the network tab, confirm the purchase event carries a well-formed items array, decide whether an All Pages trigger on a Hotjar tag is right for this client. Container Audit does the mechanical cross-referencing that eats the first forty minutes of that session, the same way every time. It will not skip the consent check on tag 47 because tag 46 looked fine.

What it cannot do is stated on the page, in the boundary text that every export also carries: "Container-only audit: this proves CONFIGURATION, not runtime behaviour. It cannot confirm firing timing, dataLayer contents, PII in actual hits, or live consent behaviour." The six runtime checks it lists are the manual audit's core: consent timing on a fresh load, double-firing in DebugView, PII in collect requests, whether custom-event triggers' events actually push, ecommerce items integrity, and cross-domain linking. For the dataLayer side of that list, the ecommerce dataLayer blueprint is the reference to check against.

Limits and when to use something else

The ten-page ceiling per list is the main hard limit. Very large containers will hit it, and the tool says so, but a truncated audit is still a partial one.

The audit reads one workspace. It does not read published versions, so "unused variable" means unused in this draft; confirm nothing published relies on it, because GTM will let you delete a referenced variable and silently break the reference. If your team runs many parallel workspaces, the agency workspace workflows post is worth reading before deleting anything.

It checks configuration, not data. If the question is "why did purchases drop 30% on Tuesday", that is a job for GA4 Monitoring, which compares daily event counts and posts to Slack. If the question is "is this tag firing right now with the right parameters", use Tag Verification or Preview mode. If the question is about the GA4 property configuration rather than the container, GA4 Audit covers that side.

Custom HTML that injects a script the audit cannot read is reported as "Worth a look", not as clean, and a tag type not in the registry is flagged at Low so a new vendor tag never passes unaudited. The tool prefers to say it does not know.

Start with the container you trust least

Pick the container that has had the most hands on it and audit its default workspace. Filter to High and Critical, fix the paused conversion tags and unset consent settings with the buttons, export the rest as Markdown, and book the manual session for the six runtime checks. Run it again next month. Open Container Audit to start, or see the features page for how it sits alongside the other tools in AI Tag Manager.