'Almost Right' Agent Code Is Worse Than Wrong Code. It's Devs' Top AI Complaint
Book: LLM Observability Pocket Guide Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools Me: xgabriel.com | GitHub A support ticket says some orders never show up in a customer's order history, and only for some customers. Someone who never saw the change opens the pagination helper and finds Math.floor where Math.ceil belongs. Proving it takes the afternoon. Three weeks earlier, an agent wrote that helper. The tests were green and the 40-line diff read the way you would have written it, so you approved it before your coffee cooled. That bug was never wrong enough to get caught. In Stack Overflow's 2025 Developer Survey, 66% of the 31,476 developers who answered the question on frustrations with AI tools picked "AI solutions that are almost right, but not quite." It was the most common answer. Second, at 45.2%, was "Debugging AI-generated code is more time-consuming." Here is my take: almost-right agent code is worse than wrong code. Wrong code costs you a retry. Almost-right code costs you a bug in production, found later by someone with less context than you had at review time. What developers actually said The same 2025 survey page shows the trust problem behind that frustration. More developers distrust the accuracy of AI tools (46%) than trust it (33%). Only 3.1% highly trust it. And 84% use AI tools or plan to, up from 76% the year before. Most developers use these tools, and 51% of professional developers use them daily. Many of them doubt what comes out. That is a workable position, as long as the doubt turns into checking. It usually turns into reading. Stack Overflow's 2026 AI results don't repeat the frustrations question, so 2025 is the latest reading on "almost right." The 2026 page does have this: 48% of respondents say they trust AI "when they can easily validate the answers." Reading a diff is not validating it. Wrong code is cheap Wrong code fails loudly. It doesn't compile or a test goes red. Sometimes the agent itself says it couldn't finish. You throw it away and try again, and the cost is a few minutes and some tokens. Almost-right code compiles. It passes the happy-path test and looks like code your team writes. So it passes the review it gets, which on a busy afternoon is a skim. Then it lands. The bill comes later, and it's bigger. The person debugging it doesn't have the prompt or the turn where the mistake went in. They have a symptom and a git blame pointing at a function that looks fine. There is data that AI-written PRs carry more logic errors. CodeRabbit's December 2025 report looked at 470 open-source pull requests (320 AI-co-authored, 150 human-only) and found about 1.7× more issues in the AI ones, with logic and correctness issues 75% more common. Two caveats: CodeRabbit sells AI code review, and the authors say they "cannot guarantee all the PRs we labelled as human authored were actually authored only by humans." The obviously broken part never ships. The one that is almost right does. The bug from the opening fits in a few lines: // paging.mjs export function lastPage(total, pageSize) { return Math.floor(total / pageSize); } It looks right. With 100 orders and 20 per page it returns 5, which is correct. A test for the case the agent had in mind passes too. Here it is, written for Node's built-in test runner: // paging.test.mjs import { test } from "node:test"; import assert from "node:assert/strict"; import { lastPage } from "./paging.mjs"; test("100 orders, 20 per page", () => { assert.equal(lastPage(100, 20), 5); }); That test passes against the wrong code. Add one order and the answer should be 6. Math.floor(101 / 20) is 5, so the 101st order never gets a page. One more test catches it before anyone ships it: test("a partial last page still counts", () => { assert.equal(lastPage(101, 20), 6); }); The fix is Math.ceil. The point is that no amount of staring at the first version would have made you more confident than that one red test. One final diff is where almost-right hides An agent works in turns. It reads files, edits, runs something, edits again. You usually see the result once, as one diff at the end, with every turn squashed together. In a 600-line diff where 590 lines are fine, the 10 bad ones sit between good ones. The good lines buy trust you then spend on the bad ones. The longer the diff, the more your review turns into a skim, and the skim is exactly the review almost-right code passes. One long diff gets a skim. Short pieces, each with a check that runs, get a verdict. Two habits change that. Check each piece of work while it's small, ideally per turn. And make "done" something a machine runs instead of something you feel after reading. Make "done" a command that runs Start with a script any agent can be told to run, and that you run before you accept the work: #!/bin/sh # scripts/done.sh - the work isn't done until this passes set -e npx tsc --noEmit npm test set -e stops at the first failing command, so a red type check never hides behind a green test run. Drop the tsc line if the repo isn't TypeScript, and make sure npm test runs something, for example "test": "node --test" in package.json. Then wire it into the agent so it can't report "done" without it. In Claude Code, a Stop hook fires when Claude finishes responding, and exit code 2 from that hook "sends Claude back to keep working." For other agents, check their docs for a way to run a command when a turn ends, or run the script yourself before you accept anything. I build Hermes IDE, so weigh this part with that in mind. In Hermes, your own checks can decide when a task is done, and Land then commits, opens a pull request or merges locally in one step, with undo (README). The other half is reviewing in small pieces. Hermes saves every agent turn, so you can diff or restore a single turn, with undo. The Review Desk (⌘G, or Ctrl+Shift+G on Windows and Linux) shows those changes by turn or by file. The Review Desk (⌘G) in By turn view: two turns (T1: 3 files +69 −1, T2: 1 file +1 −0), turn 1's diff of src/db.ts adding a refunded status, the changed files, and a commit message drafted from the turns. In that view, T2's single line gets read on its own. Squashed into one diff with T1's 69, it would be the kind of line where a floor slips past. What checks won't catch Checks only catch what someone thought to check. The paging test exists because someone thought of 101 orders. If the agent writes the tests for its own code, they can carry the same misunderstanding as the code. So read the tests before you read the implementation, and write the edge case yourself when it matters. Hermes doesn't judge whether code is correct either. It shows you each turn and leaves the decision to you. It never answers a permission prompt for you and never types into a terminal on its own. Start with the cheapest version: write the 101-orders test for whatever paging helper your agent last touched. What's your "almost right" story? Was it caught in review, by a test, or by a customer? Tell me in the comments. If this was useful A done-check is the smallest eval there is: a command that says whether the output is right. When an LLM feature runs in production, the same question turns into traces and evals, and the LLM Observability Pocket Guide is my short guide to picking the tools for that. If you want to review agent work turn by turn on your own repo, Hermes IDE is a free download for macOS, Windows and Linux, source-available under BSL 1.1 on GitHub, and not affiliated with Nous Research, Anthropic, OpenAI or any other agent vendor.
This is a summary aggregated from Dev.to. Read the complete article on the original site:
Read full article at Dev.to