Pasting AI code because it runs feels productive and for today it is! I this post I want to explain why every unread line is quiet debt that comes due the day something breaks.
The most common code in a beginner project right now is code the beginner never read. It came out of a chat window, it ran on the first try and it went straight into the repo because it worked and there were four more features to build before dinner.
This isn't a lecture. Everyone pastes, including people with fifteen years of experience and the pull is real because on the day of the paste the code is genuinely working and the backlog is genuinely long, so it's hard to point at anything that went wrong. For today, nothing did. The trap is what quietly doesn't get built while the pasting happens.
"It works" is carrying a lot of weight
Here's the kind of thing a model hands out a hundred times a day. Simplified on purpose, but its cousins are everywhere:
getUser.js
// this code has a deliberate gap
async function getUser(id) {
const res = await fetch("/api/users/" + id);
const data = await res.json();
return data;
}
It runs. The page renders, the ticket moves to done and nobody's going to think about this function again. While the API is healthy that's really the whole story.
Now picture the server having a bad day three weeks later. The endpoint returns a 500 with an HTML error page. fetch doesn't reject on HTTP errors, MDN is very clear about this: a 404 or a 500 still counts as a perfectly successful fetch. Surprising, I know. So the code sails on to res.json(), which tries to parse an HTML page as JSON. The app dies somewhere far away from this function, with an error like Unexpected token '<', "<!DOCTYPE "... is not valid JSON pointing at whatever innocent component happened to call it.
Anyone who'd actually read this function would've asked the obvious question, what happens when the request fails, and found the missing res.ok check in a minute. Pasting skips that question. So now it's a debugging session inside a stranger's code that happens to live in your repo, with no mental model, no memory of writing it and an error message aimed at the wrong file. The code doesn't break on the day it gets pasted, it breaks on the day it's understood least.
The students aced practice and failed the exam
Turns out somebody measured this exact trade. Wharton researchers gave nearly a thousand high school students in Turkey GPT-4 for math practice. The group with unrestricted access did 48% better on practice problems than students working alone. Then came the exam, no AI allowed. That same group scored 17% worse than the students who never saw the tool. Practicing with answers on tap left them weaker than if they'd never had it.
The study had a second group and I think it's the one that matters. Those students got a version tuned to coach instead of solve: hints, explanations, questions back, no direct answers. They did 127% better during practice, and on the exam the harm simply vanished. They landed level with the control group. Same model underneath. The whole difference was whether it handed over answers or made the student do part of the thinking.
Adults don't measure any better, honestly. METR ran a randomized trial where 16 experienced open source developers worked through 246 real issues, sometimes with AI tools and sometimes without. With AI they took 19% longer. They'd predicted a 24% speedup going in, and after the study, having lived through the actual slowdown, they still believed AI had made them about 20% faster. That gap between feeling and fact should worry anyone who's sure the tool is helping them learn.
One more number, because it shows where the lost time goes. In the 2025 Stack Overflow survey the most common frustration with AI tools, named by 66% of developers, was solutions that are almost right but not quite. Almost right is exactly the code that can't be shipped unread. The gap between almost and right stays invisible until something falls into it.
Thirty seconds before you paste
The fix isn't to stop using AI and it isn't to hand-type everything as penance. Typing was never the skill. The fix is a small habit wedged into the moment the cursor hovers over paste, and any one of these three versions works:
Make the model explain it. Before accepting the code, ask "walk me through this line by line, and tell me what happens when it fails." One extra message. The model is endlessly patient, it never thinks a question is dumb, and its answer will regularly surface exactly the kind of thing that fetch gap above is. This is the mode the coached group in the Wharton study lived in, and they're the ones who survived the exam.
Explain it back in plain words. Go through the snippet and finish the sentence "this line is here because..." for every line, out loud or in a scratch comment. Anywhere the sentence can't be finished, that's the line to sit with. Finding it is the whole point of the exercise.
Change one thing on purpose. Rename a variable and watch what else has to move. Delete the await and see what breaks. Feed it an id that doesn't exist. Breaking code deliberately, in a place you control, is the cheapest education in this field. Staring at the wreckage of something you broke on purpose is how most engineers I know actually learned async, whatever the tutorials say. And it's the only one of the three habits that leaves the kind of scar you'll still remember next month.
Okay, but senior developers paste code they didn't write all the time. True, and the move only looks identical. A senior skims a pasted snippet and their brain quietly diffs it against ten years of patterns: the missing error branch, the connection that never closes, the loop that will hurt when traffic doubles. All of that happens in about four seconds and they don't even notice they're doing it. They can afford the shortcut because they already paid for the map. A beginner making the same motion is skipping the map-drawing itself. That was supposed to become their career. That worry has a whole article of its own in The Junior Developer Pipeline Is Broken.
So the bar worth adopting is narrower than "write everything yourself" and much narrower than "trust nothing." It's this: never ship a line you couldn't defend if a teammate pointed at it and asked "why is this here?" The answer can be boring, "it retries twice because the payment API flakes sometimes" is a perfectly good defense. And "honestly, no idea yet" is fine too, as long as five minutes of finding out comes right after. The only losing move is shipping the line and hoping nobody ever asks.
Debugging skill is built almost entirely out of accumulated mental models of code that actually got read is the long version of why). A snippet read before it's accepted deposits a little into that account. An unread one's a loan, and the interest arrives during some future outage, at the worst possible hour, obviously.
And that's the whole fork in the road. The beginners who read the code they accept turn into the people who can fix anything. The ones who don't stay stuck at "it works until it doesn't."
Thanks for reading! English isn't my first language, so I use AI to polish the grammar. Everything else here - the ideas, the code, the opinions - is mine.
Enjoyed this one? Let's stay in touch — I'm on LinkedIn, always happy to chat, swap ideas, or just say hi. 👋

Top comments (0)