My analytics pipeline pulled App Store install data by matching a report named "App Store Downloads". Apple renamed that report to "App Downloads" with no changelog. The substring match stopped matching, the code fell back to a different report that has zero install rows, and zero rows got read as a real, legitimate zero. For a stretch of days, several apps showed fabricated install numbers up to roughly 70x their real values, and everything looked fine.
How I found it
The numbers looked too good. One app's dashboard showed a burst of installs on a single day that did not line up with anything else I knew about it. I opened App Store Connect's own UI and compared, and the real number for that day was a fraction of what my pipeline reported. A different order of magnitude, not noise.
The bug
Apple's Analytics Reports API exposes several named reports. My code picked the installs report by matching its name:
SOURCE_REPORT_HINTS = ("app store downloads",) # substring match
report = next(
(r for r in available_reports
if any(h in r.name.lower() for h in SOURCE_REPORT_HINTS)),
None,
)
if report is None:
report = fallback_report # a different report, no install rowsTwo things stacked up. First, Apple renamed the report. "App Store Downloads" became "App Downloads", the word "Store" dropped out, my substring stopped matching anything, and report came back None. Second, the fallback. When the name match failed, the code fell through to a different report that has no install rows, and its downstream logic saw zero matching rows and treated that as a real, genuine zero. A failed lookup and a true zero produced the same value, and nothing told them apart.
So the pipeline confidently emitted wrong numbers. Across the affected apps the reported figures ran up to about 70x the real installs, and no alert fired, because from the code's point of view it had pulled a report and found some rows.
A fail-silent fallback turns a missing signal into confident, wrong data.
The fix
The immediate fix was to match both names:
SOURCE_REPORT_HINTS = ("app store downloads", "app downloads") # + newer Apple namingThat is a patch. The habit worth keeping is to fail loud when a name match that should find exactly one report comes back with zero, instead of falling through to something plausible. Anywhere you string-match a vendor's field or report name, a one-line assertion that the match count did not drop to zero would have caught this the day Apple shipped the rename. The only reason I caught it at all was that a number looked wrong and I opened the vendor's own dashboard, which should not be the detection system. The same shape shows up whenever a passing check hides wrong data, like the monitoring guard that froze a dashboard for three days. Vendors rename fields without a changelog. Their internal report names were never a contract I signed, and code that matches on them instead of a stable ID breaks the next time they do.