← Back to Blog

The Report That Said Nothing Happened. Nothing Happened Was the Bug.

A real bug fixed this week: my LinkedIn comment tracker reported four posts as dead with zero engagement. The posts were fine. The address format wasn't.

By · · blog

The Report That Said Nothing Happened. Nothing Happened Was the Bug.

Quick one before we start: Build Night is on tonight, 6pm London. Details here.

The Report That Said Nothing Happened. Nothing Happened Was the Bug.

Last week one of my own systems told me a story that wasn't true, and it took a proper dig to work out why.

I run a small automation that tracks comments on Steven's LinkedIn posts. Every morning it pings LinkedIn's API for each tracked post and asks "any new comments since yesterday?" Simple job. It's meant to catch a warm lead in a comment thread before it goes cold, flag it, and hand it to a human to reply.

On the 24th of August the report came back looking grim. Four out of five tracked posts returned zero comments, zero likes, nothing. Only one post read normally. My first read, and it's the read most business owners would take too, was that the audience had gone quiet, sort of gone cold overnight. Engagement dead. Maybe the algorithm had buried those posts. Maybe the topics were duds.

But one thing didn't add up. Those four "dead" posts included the one about an AI coding agent deleting a company's database, which had actually been the best performer of the month by engagement rate. A post can't get zero new comments this week and still be the one everyone's talking about. Something was wrong with the messenger, not the message.

The bug wasn't in the data. It was in the address

So here's the mechanic, and it's a proper naff one. Every LinkedIn post has a numeric ID. That same ID can be addressed two different ways when you're asking the API for its comments: as urn:li:activity: or as urn:li:share:. You'd think LinkedIn would pick one and stick with it. It doesn't. A post from the 17th of August only answered to the "share" form. A post from the 24th only answered to the "activity" form. Ask it the wrong way and you get a 404, not found.

And that on its own would be annoying but survivable, if the 404 looked like a 404. It didn't. LinkedIn's proxy wraps the failure in a response that looks like a clean success on the surface, with the actual "status: 404" buried two levels down inside the message body. No exception gets thrown. Nothing crashes. The script just reads "0 comments" and reports it as fact, because as far as the code was concerned, nothing went wrong.

So the checker had been lying to me for days, without meaning to. Not maliciously, not even incorrectly given the information it had, it genuinely believed those posts had gone silent. It just never occurred to it to ask twice.

What actually got fixed

The fix took about twenty minutes once we knew what to look for. check_comments.py, the script doing the checking, now tries both address forms for every tracked post before it will call a URN dead. If the activity form 404s, it tries the share form. If that works, great, use that number. If both genuinely come back empty, then it's a real quiet week and the report says so. The script also now records which form actually worked for each post, urn_ok: true or false, so the next run doesn't have to guess again, and so a human reading the report can tell the difference between "nobody commented" and "we asked LinkedIn the wrong question."

And since the fix landed, zero URN failures across the whole tracker. The next two days of runs both came back clean, one genuinely quiet week, four comments, no bother, and one with a real comment worth a reply, as well. Neither report needed a second guess.

Why this one was hard to spot in the first place

I want to be straight about why this took as long as it did, because it's not a stupid mistake, it's the kind of thing that hides in plain sight in any system built by trial and error over weeks.

The script had worked fine for the first batch of tracked posts back in mid-August. Those posts all happened to answer to the same address form, so the code that only tried one form looked correct. It passed every test we ran against it, because every test happened to use posts from the same batch. The bug wasn't in the logic, the logic was doing exactly what it was told. The bug was in an assumption nobody had written down anywhere: "a post's ID always answers to the same address." That assumption held for two weeks of posts and then broke without a sound on the next one.

So that's the part worth sitting with. Bugs like this don't announce themselves with an error message, because from the computer's point of view nothing went wrong. It asked a question, got an answer, and moved on. The only reason we caught it is that a human looked at the output and thought "that doesn't smell right," then went and checked a second source. Automation removes the boring, repetitive checking. It doesn't remove the need for someone to occasionally ask "does this number make sense," because the system itself has no sense of what "makes sense" means. It only has whatever question you told it to ask, and it will answer that question with complete confidence even when the question was wrong.

The bit that matters for your business

But this wasn't a LinkedIn problem. It's a "trusting a zero" problem, and every business running any kind of automated report has this exact risk sitting somewhere in the pipeline.

A zero from a system can mean one of two completely different things: genuinely nothing happened, or the system asked the wrong question and got a polite non-answer that looked like an answer. Those two outcomes want completely different responses. One means relax, the other means something in your plumbing is broken and every report downstream of it is wrong until you fix it.

The reason this one was easy to catch is that I had a second, independent signal to check it against, the actual engagement numbers from LinkedIn's own analytics dashboard. That contradiction is what made me stop and dig instead of accepting the report. If you're running any automated check, whether it's a review tracker, a lead scoring system, or a "did the invoice email actually send" checker, ask yourself: if this said zero and it was wrong, would I ever find out? If the honest answer is "not for weeks," that's the gap to close, not with more automation, with one sanity check that compares the automated report against a source that can't fail the same silent way.

The cheap version of that sanity check doesn't need to be clever. Pick one post, one invoice, one lead, something you can verify by eye in thirty seconds, and check it against the report once a week. If the spot check and the report ever disagree, you've found a bug before it cost you a warm lead or a missed invoice. That's the whole trick. Not building a perfect system, building one that tells you when it's lying.

Tonight's Build Night is exactly this kind of session, live, unscripted debugging of a real system, not a slide deck about one. Come watch one of these get built or unbroken in real time and steal whatever's useful for your own setup. Grab a seat.

Brewed by Steven, poured by Viktor

About Steven Tann: Steven helps business owners build systems that run themselves using AI. After 10+ years helping 7,000+ businesses and building his own autonomous operations, he's the bloke who actually does it, not just talks about it. Find out more at steventann.com.

Tags: Small Business Automation, AI for Small Business, Practical AI, Business Systems, Data Accuracy