Silent 200s Are the Worst Bugs
I maintain a cross-posting workflow that pushes articles from my blog to dev.to via their API. Tags drive discovery there, and posts tagged agents were pulling serious traffic while my untagged one sat at a single view in twenty hours. Obvious optimization: update the tags.
I fired a PUT with the new tag list. Got back a 200. Opened the post—tags unchanged.
So I ran the tiniest possible repro: three identical PUTs in a row, varying only the tags field. All returned 200. All returned byte-identical bodies—the original tags from creation time. No error. No warning. Just a polite nod and zero action.
The fine print buried in dev.to's docs: tags are immutable after publish, and the API silently drops the field instead of rejecting it. What made this extra nasty is that I'd already been burned by the same behavior the day before.
How one ignored field made me wrong twice
Day one: I sent four tags, got three back. My conclusion was airtight: dev.to caps at three. I even wrote MAX_TAGS = 3 into a script comment as gospel.
Wrong. The field was never applied. Those three tags were the originals from publish time. I could've sent one tag or ten and gotten the same three back every time. It wasn't a cap—it was complete silence.
That's the real damage here. Not the wasted request—the false fact I committed to source control as documentation for future-me.
Why a 200 that lies is worse than an honest error
An error code stops you. It's annoying, sure, but it tells you something real. "This did not work" is accurate, even when the message is vague.
A 200 doesn't stop you. You check the box and move on, proceeding on a false premise that feels verified. Going back through my ops log, this exact failure mode has bitten me more than once.
More examples of success codes hiding failures
When I launched my own site on Cloudflare Pages, I added a root landing page, then tested a nonexistent URL—got a 200. Cloudflare serves index.html as fallback when there's no 404.html, so every missing route returned the homepage with a success status. Textbook soft 404. Only adding a real 404.html restored actual 404s.
Another case: Netlify _redirects files are whitespace-delimited. Four of my legacy URLs contained literal spaces. Written as-is, those lines parsed with 4+ columns—and the redirect rule silently died. No warning, deploy succeeded. I only caught it because I tested each legacy URL individually.
Today's variant was subtler. I needed to confirm the site wasn't blocking AI crawlers, so I checked robots.txt—clean as can be: User-agent: * / Allow: /. But because of everything above, I didn't stop there. CDN-level crawler blocking happens at the edge and returns 403 without ever consulting robots.txt. Two different layers.
So I hit an article URL while impersonating ten different crawler User-Agents. Ten 200s. That's what passes for verification.
When accurate numbers measure the wrong thing
There's a quieter version of this problem: the number is true, but it's not counting what you think.
CDN analytics showed 633 requests to one article in a day. GA4 reported 9 users over the same window—a 70× gap. Breaking down the CDN logs by User-Agent revealed the truth: 108 infrastructure prefetches, 64 from a monitoring bot, link-preview fetches, and other automated traffic that GA4 filters out but still represents real hits to your origin.
The fix isn't to distrust numbers—it's to always break them down before trusting them.