Published 4 min read
AI fixed the bug. Who checked the fix?
AI can find a defect, propose a patch and write tests. The difficult part is proving that the change solves the problem without breaking something else.
Nick TaylorFounder, Pitstop Technologies

Every developer knows the feeling: fix one thing, refresh the page, discover something else has broken. The cat in this picture has clearly been through the release process.

Reader-supplied reference image, hosted on SitePoint’s community CDN. The joke is older than the current wave of coding assistants.
AI changes how quickly we can produce a proposed fix. It does not remove the awkward question underneath: did we understand the problem, or did we just make its most visible symptom disappear?
I use coding assistants, but I still need to explain why a fix works. A confident explanation is useful only if the code and checks support it.
Independent review loop
The patch needs a second line of evidence.
A repeated payment event dispatches the order twice.
Before the fix
event_A → dispatch
event_A → dispatch2 dispatches. One order.
Acceptance condition
event_A → dispatch
event_A → no-op1 dispatch, even after retry.
Repeat the event, including concurrent delivery. Inspect the resulting business action.
If the independent check fails, return to the cause. A confident explanation is not a passing result.
AI finding bugs is real. So is the review work.
There are concrete examples beyond generating another contact form. The Node.js project’s October 2026 security advisory credits OpenAI Codex Security researchers with reporting a flaw in its bundled Brotli decoder. That is a specific discovery with a vendor advisory and a fix. That is not a reason to assume every AI-generated patch is safe. Source: Node.js security release.
The distinction matters. Finding a suspicious path, reproducing a defect, choosing a fix and safely releasing it are different jobs. An assistant can contribute to all four, but progress on one does not establish completion of the others.
I want AI involved where it helps me inspect more context, challenge an assumption or try a better explanation. I do not want an impressive wall of generated tests to become a substitute for understanding what they prove.
Start with the failure, not the patch
Imagine a booking form that loses the customer’s budget when they change language. This is a hypothetical example, but it is the kind of small defect that makes a business look careless.
A quick suggestion might put the budget into a URL parameter. The demonstration now works. But should that information be in the address bar? Does the destination recognise the same budget bands? What happens when someone edits the parameter, opens a second tab or returns tomorrow?
Before changing code, I would write down the intended behaviour: an ordinary language switch preserves the current enquiry, the customer can correct it, invalid values are rejected, and unrelated visitors never receive someone else’s details. That gives the fix a boundary.
Then reproduce the failure. If a test cannot distinguish the broken behaviour from the desired behaviour, a green result is not useful reassurance.
The tests need an independent opinion
Asking the same assistant to implement a change and then prove its own implementation correct can create a very tidy circle. The tests may repeat the assumptions that caused the problem.
For the booking example, useful checks would cover a valid budget, an unsupported value, an interrupted journey and a return to the original language. The expected outcome should come from the product requirement. It should not be copied from whichever value the new function happens to return.
I also want to check the boundary where browser and server meet. A unit test can prove that a field-mapping function works while the actual form submits a different field name. Neither the customer nor the business gets much comfort from that distinction.
A smaller change is easier to trust
When a bug fix turns into a new abstraction, a dependency swap and a rewritten component, the review has become harder. Sometimes a structural change is justified. It needs a reason beyond “the assistant suggested it”.
My default would be the smallest complete correction: fix the cause, cover the important failure, and check the neighbouring behaviour. For a payment change, that includes retries and repeated messages. For a visual change, it includes a narrow screen, keyboard use and reduced motion. Different work needs different evidence.
A passing test suite is one part of that evidence. So are the diff, the running product and a clear explanation of what remains unverified.
Measure the result after release
A finished patch should leave the next person with a useful trail: what failed, why this change addresses it, what was checked and how to detect a recurrence. Operational checks should reveal failure without dumping private customer information into logs.
AI is useful here when it helps me find the cause, examine alternatives and check the result. Producing more code is easy; deciding what belongs in the release takes judgment.
For a business owner, the question is simple: who checks the work and takes responsibility when it goes wrong? That matters more than whether a person typed every character.
See how I approach software projects, or tell me what needs fixing. We can agree the investigation and scope before promising a solution.


