A Heap defined event dropped to zero volume after a frontend redeploy — why?
answer
- check the deploy timestamp first
- zero, not lower, is the tell
- the rule broke, not the capture
- hashed class names, restructured DOM
- raw data survives — redefine and recover
basics
~20 sMost likely the definition's selector no longer matches the rendered markup — a CSS refactor, generated class names, a DOM restructure or copy change broke the rule. Autocapture kept recording the clicks; they simply stopped being classified as that event.
solid answer
~50 sA Heap event defined over autocaptured data is a matching rule against DOM structure, classes, text and URL. A redeploy that renames classes (CSS-in-JS or utility hashes), reshapes the element hierarchy, changes the button label or moves the flow to a new route silently invalidates that rule. The tell is a drop to **exactly zero starting at the deploy timestamp**, with history intact — the raw interactions are still being captured, they just match nothing. Diagnose by correlating the drop with release time, then re-inspecting the definition against the live markup. Rule out the alternatives: the element genuinely disappeared, the snippet failed to load, a consent-management change now blocks capture, or the URL filter stopped matching. The fix is to redefine on stable hooks — an `id` or an agreed `data-` attribute the team treats as a contract — rather than generated classes or localised text, and to alert on defined-event volume so the next break is caught in hours, not at quarter-end.
code
text · 8 lines# before the redeploy - definition matched .btn-primary.checkout
<button class="btn-primary checkout">Place order</button>
# after a CSS-in-JS refactor - same button, no matching class
<button class="css-1x9kd7f">Place order</button>
# stable hook the definition should have been anchored on instead
<button id="checkout-place-order" data-analytics-id="checkout_place_order">Place order</button>go deeper
Know that a Heap event is a rule matching page elements, so changing the markup can stop it matching even though users still click the button.
Explain what invalidates the match — hashed class names, DOM restructuring, copy or route changes — and why the raw interactions keep being captured regardless.
Demonstrate the diagnosis: correlate with the deploy, check whether sibling events survived, exclude snippet and consent failures, then redefine and recover the missing window.
Own the prevention: stable analytics attributes treated as a frontend contract, volume alerting per reporting event, definition ownership, and a decision on whether the semantic layer should live in the vendor UI at all.
## Why this failure is specific to autocapture With hand-instrumented analytics, the tracking call lives beside the component: refactor the markup and the call travels with it, and if it is deleted, the diff shows it. Heap's model puts the event definition in a vendor UI, matching on the rendered DOM. Nothing in the frontend repository references it, no test covers it, and no code review notices when a change breaks it. This is the single most common operational failure on autocapture platforms and the reason the question gets asked at senior level. ## The signature of a broken definition Read the shape of the drop before theorising: - **Zero, not reduced, starting at a deploy boundary** — a matching rule that no longer matches. Traffic-driven declines are gradual and rarely hit exactly zero. - **History unchanged** — past periods still show volume, because the raw interactions were captured and remain classified. - **Sibling events on the same page still healthy** — capture itself is working; only this rule broke. If *every* event on the site went to zero, suspect the snippet or consent gating instead. ## What actually breaks the match - **Generated class names.** CSS-in-JS libraries and utility frameworks emit hashed or churning class names. A definition anchored on `.btn-primary.checkout` dies the moment the build produces `.css-1x9kd7f`. - **Hierarchy changes.** Wrapping a button in a new flex container, moving it into a modal, or introducing a portal changes the DOM path a selector-based rule relies on. - **Text changes.** Definitions filtered on visible label text break on copy edits — and break per-locale the moment internationalisation ships, which produces a partial rather than total drop. - **Route changes.** A page filter pinned to `/checkout` misses `/checkout/v2`; a query-parameter filter misses a new parameter order. - **Rendering-surface changes.** Moving the flow into a cross-origin iframe or a canvas-rendered widget removes the elements from Heap's reach entirely. ## Differential diagnosis Before you rewrite the definition, exclude the alternatives, because two of them are far more serious: 1. **The snippet stopped loading** — a CSP change, a bundling error, a tag-manager edit. Symptom: *all* events flatten, including pageviews. 2. **Consent gating changed** — a new CMP configuration or a default-deny in a region. Symptom: volume falls to a residual, often with a geographic skew. 3. **The element genuinely went away** — the feature was removed or A/B-tested off. Symptom: zero volume *and* the flow no longer exists; the analytics are right and the product changed. 4. **Identity or filtering changes upstream** — a report scoped to a segment whose definition also changed. Only after those are ruled out is "the selector broke" the answer. Then open the definition, compare it against the current rendered markup, and re-pick the element. ## The repair, and the systemic fix Repair is cheap and has a pleasant property: because raw interactions were captured throughout the outage, redefining the event **recovers the missing period**. That is the one place autocapture beats instrumentation outright — a missed tracking call loses the data forever, a broken definition loses only the classification. The systemic fix has three parts: - **Anchor on stable hooks.** Ask the frontend team to add explicit `id`s or dedicated data attributes to elements that back reporting events, and treat those attributes as a contract that code review protects. Never anchor a reporting-critical event on a generated class or a localised string. - **Monitor the events, not just the pipeline.** Alert on per-event daily volume — a percentage drop or a zero-day — using the warehouse copy of the data if you sync one. A broken definition is invisible unless something watches for it. - **Put definitions in the release path.** A short checklist item for redesigns of instrumented flows, an owner per reporting event, and edit permissions on the definitions that feed dashboards. ## What an interviewer wants to hear The strong answer moves in this order: read the shape of the drop, correlate with the deploy, rule out snippet and consent failures, confirm the selector against live markup, redefine and recover the lost window, then close the loop with stable hooks and volume alerting. A weak answer jumps straight to "the data was lost" — it was not — or blames Heap for something the deploy did.
- Is the data for the outage window lost?No, and that is autocapture's real advantage. The interactions were captured throughout; only the classification stopped. Fix the definition and the missing period is reclassified and reappears in reports. A missed hand-instrumented tracking call, by contrast, loses that period permanently.
- How would you tell a broken definition apart from the Heap snippet failing to load?Look at the blast radius. A broken definition kills one event while sibling events and pageviews on the same pages stay healthy. A snippet failure — CSP change, bundling error, tag-manager edit — flattens everything, pageviews included. A consent-management change usually leaves a residual with a geographic skew rather than a clean zero.
- What would you change so this does not recur?Anchor reporting events on stable `id`s or agreed data attributes that code review protects, not on generated classes or localised label text. Alert on per-event daily volume so a zero-day pages someone within hours. Add instrumented flows to the redesign checklist and assign an owner to each reporting-critical definition.
- Why is anchoring a definition on visible button text risky?Copy changes break it, and internationalisation breaks it per locale — you get a partial drop that looks like a traffic decline rather than an obvious zero. Text also drifts through A/B tests. Structural hooks that the team has agreed not to change are far more durable.
saying these in an interview costs you the question
- Assumes the interactions during the outage are permanently lost
- Blames Heap rather than checking the deploy diff
- Skips ruling out snippet failure or consent gating
- Re-anchors the fix on another generated class name
- Fixes the one event without adding volume monitoring