claude-skills/marketing-skill/skills/analytics-tracking/references/debugging-playbook.md
Reza Rezvani 1851c8fb09 fix(plugins): restructure 9 multi-skill domain plugins into ./skills/ layout
Same root cause as #587/#591 — Claude Code's runtime loader rejects
array-form skills paths like ["./content-production", "./ai-seo", ...]
even when each entry is a valid subdirectory containing SKILL.md.
`claude plugin validate` accepts them but the loader does not.

The proven canonical layout (used by self-improving-agent in #536):

  <plugin>/
  ├── .claude-plugin/plugin.json    skills: "./skills"
  └── skills/
      ├── <skill-1>/SKILL.md
      ├── <skill-2>/SKILL.md
      └── ...

Restructured 9 multi-skill domain plugins:
- business-growth (4 skills moved)
- c-level-advisor (28)
- engineering (36)
- engineering-team (32)
- finance (2)
- marketing-skill (43)
- product-team (12)
- project-management (8)
- ra-qm-team (13)

Also fixed standalone plugins that had root SKILL.md + ./skills/ subdir
(agenthub, autoresearch-agent, executive-mentor, playwright-pro). The
loader rejected them despite skills="./skills" because of the conflicting
root SKILL.md (compare self-improving-agent which works because PR #536
moved its root SKILL.md). Moved each root SKILL.md into ./skills/<name>/.

Restored standalone plugin folders to their original paths after the
multi-skill restructure swept them into parent skills/ directories
(marketplace.json source paths require original locations).

Removed 7 orphaned marketplace entries that pointed to skill folders
without their own plugin.json (content-creator, demand-gen,
fullstack-engineer, aws-architect, product-manager, scrum-master,
skill-security-auditor) — these were already non-functional.

Bumped patch versions on every changed plugin and synced
marketplace.json. Marketplace now lists 29 working plugins (down
from 36).

After merge: users run `/plugin marketplace update claude-code-skills`
followed by `/plugin update --all` to pick up the working layout.
2026-05-02 22:51:20 +02:00

7.9 KiB

Tracking Debug Playbook

Step-by-step methodology for diagnosing and fixing analytics tracking issues.


The Debug Mindset

Analytics bugs are harder than code bugs because:

  1. They fail silently — no error thrown, just missing data
  2. They often only appear in production
  3. They can be caused by timing, consent, ad blockers, or just configuration

Work systematically. Don't guess. Verify at each layer before moving to the next.


The Debug Stack (Bottom-Up)

Layer 5: GA4 Reports / DebugView      ← what you see
Layer 4: GA4 Data Processing          ← where it lands
Layer 3: Network Request              ← what was sent
Layer 2: GTM / Tag firing             ← what GTM did
Layer 1: dataLayer / App code         ← what your app pushed

When something's missing at Layer 5, start at Layer 1 and verify each layer before going up.


Tool Setup

GTM Preview Mode

  1. GTM → Preview (top right)
  2. Enter your site URL → Connect
  3. A blue bar appears at the bottom of your site: "Google Tag Manager"
  4. GTM Preview panel opens in a separate tab
  5. Perform the action you're debugging
  6. Check: did the expected tag fire?

Reading GTM Preview:

  • Left panel: events as they occur (Page View, Click, Custom Event, etc.)
  • Middle panel: Tags fired / Tags NOT fired for selected event
  • Right panel: Variables values at the time of the event

GA4 DebugView

  1. GA4 → Admin → DebugView
  2. Enable debug mode via:
    • GTM: add debug_mode: true to your GA4 Event tag parameters
    • Extension: install "GA Debugger" Chrome extension
    • URL parameter: add ?_gl= or use GA4 debug parameter
  3. Perform actions on your site
  4. Watch events appear in real-time (10-15 second delay)

Chrome DevTools — Network Tab

  1. Open DevTools → Network
  2. Filter by: collect or google-analytics or analytics
  3. Perform the action
  4. Look for requests to https://www.google-analytics.com/g/collect
  5. Click the request → Payload tab → view parameters

Common Issues and Fixes

Issue: Event fires in GTM Preview but not in GA4

Possible causes:

  1. Consent mode blocking — user is in denied state

    • Check: In GTM Preview, look at Variables → Analytics Storage — is it denied?
    • Fix: Test with consent granted, or implement Advanced Consent Mode
  2. Filters blocking data — internal traffic filter is active

    • Check: GA4 → Admin → Data Filters — is "Internal Traffic" filter active?
    • Fix: Disable filter temporarily, test, then re-enable and exclude your IP correctly
  3. Debug mode not enabled — DebugView only shows debug-mode traffic

    • Check: Is debug_mode: true parameter on the GA4 Event tag?
    • Fix: Add it, or use the GA4 Debugger Chrome extension
  4. Wrong property — you're looking at a different GA4 property

    • Check: Confirm Measurement ID in GTM matches the GA4 property you're viewing
    • Fix: Compare G-XXXXXXXXXX in GTM vs. GA4 Data Stream settings
  5. Duplicate GA4 configuration tags — two config tags = double sessions + weird data

    • Check: GTM → Tags → filter by "GA4 Configuration" — more than one?
    • Fix: Delete duplicates, keep one with All Pages trigger

Issue: Event not firing in GTM Preview at all

Diagnosis path:

Step 1: Check the trigger

  • Is the trigger for this tag listed under the action in GTM Preview?
  • If not: the trigger didn't fire

Step 2: Check trigger conditions

  • Open the trigger in GTM
  • Reproduce the exact scenario step by step
  • In GTM Preview, check Variables at the moment the action happened
  • Do the variable values match your trigger conditions?

Step 3: dataLayer issue (for Custom Event triggers)

  • In GTM Preview → select the relevant event in left panel → Variables tab
  • Scroll to find event — what's the value?
  • If event name doesn't match trigger exactly: it won't fire (case-sensitive, exact match)

Step 4: Timing issue

  • If using "Page View" trigger and element doesn't exist yet: switch to "DOM Ready" or "Window Loaded"
  • If SPA: route changes may not trigger "Page View" — use History Change instead

Issue: Parameters showing as (not set) or undefined in GA4

Step 1: Verify parameter is in the network request

  • DevTools → Network → find GA4 collect request → Payload
  • Search for the parameter name (e.g., plan_name)
  • If not there: GTM variable isn't resolving correctly

Step 2: Check the GTM variable

  • GTM Preview → find the event → Variables tab
  • Find the variable for this parameter (e.g., DLV - plan_name)
  • What's its value? If undefined: the dataLayer push didn't include this key, or key name is wrong

Step 3: Check dataLayer push in your app code

  • DevTools → Console → type: dataLayer.filter(e => e.event === 'your_event_name')
  • Inspect the object — is the parameter key present and spelled correctly?

Step 4: Check GA4 custom dimension registration

  • Some parameters require a registered custom dimension in GA4 to appear in reports
  • GA4 → Admin → Custom Definitions → Custom Dimensions
  • If parameter isn't registered here: it'll exist in raw data but won't show in Explore reports

Issue: Duplicate events (event fires 2x per action)

Find the duplicates:

  • GTM Preview → find the action → how many tags with the same name fired?
  • DevTools → Network → filter by collect → count hits for the action

Common causes:

  1. Enhanced Measurement + manual GTM tag

    • e.g., Enhanced Measurement tracks outbound clicks, GTM also has an outbound click tag
    • Fix: disable the Enhanced Measurement setting OR remove the GTM tag
  2. Two GTM Configuration tags

    • Each sends its own hits
    • Fix: delete one, keep one
  3. SPA router fires pageview + History Change trigger also fires

    • Fix: disable Enhanced Measurement pageview, use only History Change tag
  4. Event fires on multiple triggers that both match

    • Fix: make triggers more specific — add exclusion conditions

Issue: Sessions/users look wrong (too high or too low)

Too many sessions:

  • Multiple GA4 Configuration tags
  • History Change trigger firing + Enhanced Measurement pageview on SPA
  • Client ID not persisting (cookie being blocked or cleared)

Too few sessions / users:

  • Consent blocking analytics for non-consenting users (expected under strict consent mode)
  • Bot filtering too aggressive
  • GA4 tags firing on wrong pages only

Sessions reset unexpectedly (user shows as new on every page):

  • Cross-domain tracking not configured
  • Cookie domain mismatch
  • GTM cookie settings incorrect

Issue: Conversions not matching between GA4 and Google Ads

Check 1: Attribution window mismatch

  • GA4 default: 30-day last click
  • Google Ads: check conversion action settings for window
  • These legitimately produce different numbers

Check 2: Conversion event names

  • In Google Ads → Tools → Conversions → imported from GA4
  • Does the linked event name exactly match the GA4 event?

Check 3: Import is linked

  • Google Ads → Tools → Linked Accounts → Google Analytics 4
  • Is the correct GA4 property linked and synced?
  • Sync can take 24-48 hours after changes

Check 4: Enhanced Conversions

  • If GA4 uses a user_id or email parameter, Enhanced Conversions can improve matching
  • Google Ads → Conversions → Enhanced Conversions for Web → Enable

Debug Checklist Template

Use this for any new tracking issue:

[ ] Confirmed exact event name and parameters expected
[ ] Verified app code is pushing to dataLayer (console: dataLayer)
[ ] GTM Preview: trigger fires at correct moment
[ ] GTM Preview: parameters resolve to correct values (not undefined)
[ ] Network: GA4 collect request appears with correct payload
[ ] GA4 DebugView: event appears within 30 seconds
[ ] GA4 DebugView: parameters present and correct
[ ] GA4 Reports: event appears (24-48h delay for standard reports)
[ ] Consent check: tested with analytics consent granted
[ ] Filter check: internal traffic filter not blocking test traffic