The last ten bugs I fixed, I fixed the same way. Stack trace in. Fix out. Apply, run, green, move on. Each one took minutes. It felt like getting better at my job.
Then a bug showed up with no stack trace. No exception. No red line to copy. Just a customer saying it didn't work and a log file that swore everything succeeded. I opened the file, put my hands on the keyboard — and realized I had no idea what my first move was.
Not "I don't know the answer." Something worse. I didn't know how to start looking.
That's when it landed: I hadn't gotten faster at debugging. I'd stopped doing the part that was the debugging — and I'd been not-doing it for so long the muscle had gone soft without me noticing. This isn't a doomer post; I paste stack traces all day and I'm never going back. But there's a specific skill AI quietly took off my hands, and it's not the one you'd guess.
Debugging was two skills wearing one name
For twenty years "being good at debugging" was quietly two different things bundled together, and we never had to separate them because you couldn't get one without the other.
The first is recall — pattern-matching a known error. You see Cannot read property 'x' of undefined, and twelve thousand hours of prior pain instantly says something upstream returned null, go look there. The stack trace points, you follow. That's fast, it's valuable, and it's exactly the thing AI is now better at than you. Good riddance — it was never the interesting part.
The second is hypothesis formation — inventing a suspect when the symptom points nowhere. The customer is locked out but every log is green. Nothing crashed. Nothing to paste. You have to generate, from thin air, a theory of what could produce this exact symptom — and then design the cheapest test that would prove the theory wrong. Observe, hypothesize, falsify, narrow. That loop is the whole craft. It's judgment, not recall.
AI ate the first skill completely. And because the two always came bundled, it feels like it got good at "debugging." It didn't. It got godlike at the recall half and touches the hypothesis half not at all — because the hypothesis half was never in the stack trace. It was in you.
The half it didn't automate, it deleted — because you stopped practising
Here's the mechanism, and it's the whole post.
AI didn't make hypothesis-forming easier. It made it skippable. The new workflow lets you jump straight from observe to fix — paste the symptom, receive the patch — without ever running the loop in the middle. And the loop in the middle was the skill.
A skill you skip every day for a year is not a skill you still have. It's a muscle you stopped loading. The reps that built it — what could possibly cause this? let me test the cheapest theory first — are exactly the reps AI now does for you on every bug that comes with a trace. So on the easy ones, you don't practise. And the easy ones are 95% of your week.
Then the hard 5% arrives — the bug with the symptom miles from the cause, the one with nothing to paste — and it wants the exact muscle you spent a year not using.
AI can fix any bug that comes with a stack trace. The ones that hurt you don't.
Why you can't see it happening
This is the cruel part: every metric says you got better.
Your bug-fix rate went up. You close more tickets, faster. If someone measured your debugging on a dashboard, the line points up and to the right. So you feel sharper, not duller.
But look at what actually improved. You got faster at dispatching bugs that were already easy — the ones where the trace did the hypothesis-forming for you. Your capacity for the hard ones, the ones that require you to invent the suspect, quietly dropped the whole time. Nothing on the dashboard shows that number, because the hard bugs are rare and you can always blame the one that stumped you on "it was a weird one."
It wasn't a weird one. It was the only kind that was ever testing the real skill. The rest were typing.
The bug that showed me the hole
Let me make it concrete, because I earned this the expensive way.
I once shipped a write path that acknowledged the request before it had actually persisted the row. Clean code. Read like a careful engineer wrote it. Demo, tests, my machine — flawless.
Then one day a retry hit at the wrong moment. The ack went out, the save didn't land, and a paying customer got locked out of their own account with no record they'd ever done the thing. No exception. No stack trace. Every log line green. Ack-before-persist.
I pasted everything I had into the AI. It had nothing to grab — there was no error, just a lie in the logs. And I sat there, and the sentence that would crack it — "what if the acknowledgement fired before the write committed, so a retry saw a half-done state?" — would not come. That sentence is the entire skill. Five years ago I'd have generated it in under a minute, reflexively, because I'd formed a thousand hypotheses like it by hand. That day it took me most of an afternoon, because I'd spent a year letting the stack trace hand me the suspect.
The AI didn't fail me. I'd let it do the one part I most needed to stay good at, and kept the part it was going to be better at than me anyway.
To be clear — this is not "stop using AI to debug"
I am not going back to reading stack traces like tea leaves. For the bug that comes with a trace, forming the hypothesis by hand is wasted motion — the trace already formed it, and re-deriving it to prove I'm a real engineer is just penance. Paste it. Take the fix. Move on. That's correct.
The danger is narrower and easy to miss:
When AI debugs the easy ones so completely that you never practise, the muscle for the hard ones atrophies — and the hard ones are the entire reason the skill was worth having. You're not trading away speed. You're trading away your only training reps, and paying for it exactly once, at the worst possible moment, on the bug nobody else can crack either.
So here's what I do now to keep the muscle:
- Guess before you paste. Before the AI gets a turn, say one hypothesis out loud: "I bet it's the cache, because the value is stale only after a write." You'll often be wrong. Doesn't matter — the guess is the rep, not the fix. You're keeping the suspect-generating muscle warm on the cheap bugs so it's there for the expensive one.
- When AI is stumped, don't escalate — close the laptop. The instinct is to reach for a bigger model, which is just more pasting. But a bug with nothing to paste is the AI telling you this one is yours. Form suspects on paper. Run the falsify-narrow loop by hand. That bug is a free training session; don't outsource the one workout that counts.
- Keep a log of the far ones. Not "bugs I fixed" — bugs where the symptom was nowhere near the cause. Ack-before-persist. The heisenbug that vanished under the debugger. The prod-only race. That list is your actual skill inventory. The stack-trace bugs don't belong on it; they were never testing you.
Why this is the exact reason I build the way I do
Here's the part that goes one level up, because it's the same logic.
I build an agent platform, and the temptation across this whole industry is to celebrate the thing that generates the fix. Look how fast it patches! But an author that patches the symptom is patching the symptom whether or not it ever found the cause — and a bug with no stack trace is precisely where "patch the symptom" and "fix the bug" come apart. The fix can be green and the mechanism still lurking.
So I never let the thing that writes the fix be the thing that certifies it. There's an author that produces the patch — paste it all the trace you like. There's a separate skeptic whose only job is to reproduce the failure and state the mechanism out loud before any fix is blessed — hypothesis-formation made into its own seat, the "what actually caused this?" that a symptom-patcher will always skip. And there's a human who owns the bugs that come with nothing to paste, because those were always going to be ours. Author, skeptic, human — that separation is the whole shape of xenition, and it's the same lesson the empty log file taught me: the fix was always the cheap part. Forming the hypothesis was the skill. Don't let the tool do the one rep you can't afford to lose.
Your rising bug-fix rate isn't proof you got better. It might be proof you stopped practising the only part that was ever hard.
Honest question for the comments: what's a bug AI genuinely couldn't help you with — no stack trace, the symptom miles from the cause — and how did you crack it? I want the one you had to think your way through, not the one you pasted. 👇
(If this made you want to guess before your next paste, a ❤️ and a 🔖 help it reach the next person whose bug-fix rate is quietly lying to them.)
Top comments (1)
Answering your honest question: a prod-only duplicated-order bug. The checkout occasionally wrote two rows for one order — only under load, only in prod. Every log line showed a single request id and reported success. No exception, nothing to paste; the AI suggestions were generic "add idempotency" advice.
What cracked it was running the falsify-narrow loop by hand, exactly the rep you describe. Cheapest falsifiable theory first: "if a retry re-enters the handler, what state would prove it did?" That led to the actual cause: the client timeout budget (3s) was shorter than the worst-case commit path (p99 4.2s), so the client retried while request one was mid-commit, and the dedupe check ran before the first write was visible — both attempts saw "no order yet" and proceeded. Symptom three layers from cause; no stack trace would ever have pointed there.
The transferable bit: writing the suspect down before touching anything turns "what could it be" into a cheap binary test — "would theory X be disproven by observation Y?" — which is what keeps the loop moving when there's no error to steer by.
And it sharpens your dashboards point: the metric that would have caught mine was client timeout vs commit p99 — a ratio, not a rate. No dashboard had it, so everything stayed green while the bug shipped.