Last week I wrote about shipping a paid API for AI agents and getting two real calls in a week. The follow-up was supposed to be about fixing the product. It turned into something else, because in the process of fixing it I hit three bugs in a row that had one thing in common:
That turns out to be the failure mode that costs the most time, and I don't see it discussed much, so here they are.
I was adding debarment records — public sanctions against companies barred from public procurement — to my business verification API. The endpoint took a parameter called inqryDiv. I passed 1.
It returned HTTP 200 with an empty result set. No error, no warning, no hint. The obvious reading: this company has no sanctions on record.
The correct value was 2. With 1, the API answers a question nobody asked and returns nothing, forever, for every company.
If I'd shipped that, my API would have told users "no sanctions found" for every single company in Korea, with a straight face and a 200 status code. That's not a broken feature. That's a feature that confidently lies.
What saved me: I happened to test against a company I knew was sanctioned. If I'd tested with a random company — which would also have returned zero, correctly — I'd never have caught it.
I built a scheduled job to enrich my index with registration numbers. Registered it with Cloud Scheduler. Ran it once manually before trusting the schedule.
The entry point had a guard to detect whether the module was being run directly, and it built the comparison URL by hand:
js // Works on my machine. Not on Linux. if (import.meta.url === file:///${process.argv[1]}) { main(); }
On Windows, process.argv[1] looks like C:\path\to\file.js, so prefixing file:/// is right. On Linux it's already /app/dist/job.js, so you get file:////app/dist/job.js — four slashes — which never matches. The guard silently evaluated false, main() never ran, the process exited cleanly, and the platform reported success.
The fix is one line (pathToFileURL(process.argv[1]).href), but that's not the interesting part. The interesting part is that a green checkmark in a scheduler dashboard is not evidence that your code ran. It's evidence that a container started and stopped without crashing. Those are very different claims.
If I had trusted the schedule instead of running it once by hand, I would have seen green checkmarks every morning for a week while the index sat untouched, and I'd have gone looking for the problem in the API, the credentials, the data — anywhere but the one line that decides whether the program starts at all.
With the job fixed, I tested search with Korean company names over curl in Git Bash. Zero results. Every time. English names worked fine.
I was minutes away from digging into the normalization pipeline — Korean text has its own encoding pitfalls, so a bug there was entirely plausible — when I ran the identical query from a local Node script instead. It worked.
The server was fine. Git Bash was mangling the UTF-8 in the URL before it ever left my machine.
This one cost the least time but taught the sharpest lesson: when a test fails, the test environment is a suspect too. I'd been treating my terminal as a neutral observer. It wasn't.
Three different layers — a government API, a container platform, a shell — and the same shape each time. Something went wrong, and every signal I had available said things were fine.
