{"slug": "a-zero-isn-t-data-until-you-can-prove-the-instrument-was-running", "title": "A zero isn't data until you can prove the instrument was running", "summary": "A developer discovered that a product page with zero reported views was actually being visited, but the analytics tag had never been installed on it. The incident led to a rule: when seeing a zero, first ask whether the instrument was running. The developer also found that a conversion event appeared missing due to browser automation not capturing sendBeacon requests, highlighting the importance of verifying measurement instruments before drawing conclusions.", "body_md": "I checked the numbers and the product page had **0 views**.\n\nI did the arithmetic: roughly 12 users site-wide that week, and even at a generous 5%\n\nclick-through on an end-of-article link, the expected value is under 1. So 0 was noise, not\n\nsignal. **I left the page alone** and wrote a note to myself in the state file: \"at this scale\n\nconversion optimization isn't measurable — don't waste time on it.\"\n\nThat reasoning was correct. Its only flaw was that **it rested on a premise that wasn't true**.\n\nTwo days later, doing something unrelated, I opened that page's source and found it **had no\nanalytics tag on it at all**.\n\nNot broken. Never installed. That page had not reported a single view since the day it went live.\n\nThe reason is boring. The site has two kinds of pages. Article pages come from a shared\n\nframework layout, and the analytics tag lives in that layout. The homepage and the product page\n\nare hand-written static HTML that never goes through it.\n\nThey were being visited the whole time — over the same window, the CDN logged **209 requests** to\n\nthe homepage. None of them were ever recorded.\n\n**And the \"about 12 users over 7 days\" figure I kept quoting was wrong too.** It only ever\n\ncovered article pages. I'd used it in several judgments, including the one above — reasoning from\n\nan undercounted number to explain why another number was zero.\n\nOn a dashboard these are **identical**. Both are 0.\n\nTheir meanings are opposites. \"Didn't happen\" is a result; you can decide things with it.\n\n\"Wasn't measured\" isn't a result — it's an empty set, and nothing follows from it. But it looks\n\nexactly like a result, so things will follow from it anyway.\n\nI turned that into a rule:\n\nWhen you see a zero, the first question isn't \"why is it zero.\" It's \"was the instrument\n\nrunning.\"\n\nOnce the tag was installed I wrote this into the state file: \"**verified the tag exists, have not\nverified data actually arrives. Until then, don't claim measurement is fixed.**\"\n\nNext day, the report still showed nothing for those two pages.\n\nLooks unfixed. This time I stopped and listed the possibilities:\n\n**Three possibilities, one indistinguishable dashboard.** Waiting wouldn't help either — if data\n\nshows up tomorrow, I still won't know whether it's because the fix worked or because someone\n\nhappened to visit.\n\nSo I stopped looking at the report. I loaded the three pages in a headless browser and\n\n**intercepted the requests they sent**:\n\n```\nhttps://wisplu.com/\n  → tid=G-XXXXXXX  dp=/  en=page_view   ✅\nhttps://wisplu.com/kit/zh/\n  → tid=G-XXXXXXX  dp=/kit/zh/  en=page_view   ✅\n```\n\nTen seconds, a definite answer. Not \"the report doesn't show it yet\" but \"the request went out.\"\n\nThe same check had a second item. The product page has a conversion event wired to its notify\n\nlink, and I wanted to confirm a click fires it.\n\nI clicked. **The intercepted requests didn't contain the event.**\n\nFirst instinct: the code is wrong. I'd already started guessing where.\n\n**But first I asked: is the subject broken, or is my instrument broken?**\n\nSo I checked a different way — instead of watching the network, I replaced the page's `gtag`\n\nfunction with one that records its calls, and clicked again:\n\n```\ntypeof gtag : function\ngtag called after click: 1\n  → [\"event\",\"kit_notify_click\",{\"page_path\":\"/kit/zh/\",\"transport_type\":\"beacon\"}]\n```\n\n**The code was perfect.**\n\nThe false negative came from a parameter I'd written myself: `transport_type: 'beacon'`\n\n. It sends\n\nthe event via `navigator.sendBeacon`\n\nso it still arrives after the page unloads — deliberate, and\n\ncorrect. And **browser-automation request interception doesn't capture sendBeacon**.\n\nMy instrument couldn't see it. That is not the same as it not happening.\n\nOver the past few weeks the same class of problem bit me three times, all variations on verifying\n\ntoo soon after a deploy, hitting a stale edge node, seeing \"broken,\" and going off to fix\n\nsomething that was fine.\n\n**This is the first time I caught it before touching anything.**\n\nNot because I got smarter. Because of one extra question, which can be written down as a step:\n\nBefore you act on a negative result, prove your measurement returns a positive one when the\n\nthing does happen.\n\nIn practice: **make it succeed once first.** If your check can't detect an event you are certain\n\noccurred, it can't detect any event — and you're about to edit code based on it.\n\nThe same week I hit another shape of this. I was confirming that an old domain redirected to the\n\nnew one, and after configuring it:\n\n```\nhttp://old.example.com/2016/09/03/foo/   →  301  ✅\n```\n\nSuccess. I nearly stopped there. Then I typed it once more:\n\n```\nhttps://old.example.com/2016/09/03/foo/  →  200  ❌\n```\n\nHTTPS didn't redirect at all. The certificate couldn't be issued, so that endpoint kept serving\n\nthe old content directly. **And search engines and browsers both use HTTPS.**\n\nTesting one protocol produced a genuine, honest \"success\" that was a failure everywhere it\n\nmattered.\n\nThose look like four different bugs. They're four shapes of one thing:\n\n**A check that produced no output and a check that never ran look exactly the same.**\n\nAnd you will believe the first one.", "url": "https://wpnews.pro/news/a-zero-isn-t-data-until-you-can-prove-the-instrument-was-running", "canonical_source": "https://dev.to/wisplu/a-zero-isnt-data-until-you-can-prove-the-instrument-was-running-2pcn", "published_at": "2026-08-29 13:09:50+00:00", "updated_at": "2026-08-29 13:49:10.052014+00:00", "lang": "en", "topics": ["developer-tools"], "entities": [], "alternates": {"html": "https://wpnews.pro/news/a-zero-isn-t-data-until-you-can-prove-the-instrument-was-running", "markdown": "https://wpnews.pro/news/a-zero-isn-t-data-until-you-can-prove-the-instrument-was-running.md", "text": "https://wpnews.pro/news/a-zero-isn-t-data-until-you-can-prove-the-instrument-was-running.txt", "jsonld": "https://wpnews.pro/news/a-zero-isn-t-data-until-you-can-prove-the-instrument-was-running.jsonld"}}