I was asked to repair an application built with vibe coding

The problem with vibe coding is not the use of AI. It is the removal of the mechanisms that let us understand, verify and evolve software. Repairing such an application begins by recovering a model of the system, not by generating more code.

Layers of an apparently complete application reveal broken connections and a lack of structure.

I was asked to repair an application created through vibe coding. It had begun like many others: an idea, a conversation with an AI and the immediate satisfaction of seeing an interface work. Then something stopped fitting together.

The application worked well except in one browser. With the same application and the same invoice, an automated OCR data extraction returned incorrect results there while succeeding in every other browser.

The temptation with an application like this is to continue exactly as it was created: describe the error, request another change and try again. Sometimes that works. It can also add one more layer to a system nobody understands.

First, recover the map

Before touching the code, I need to answer elementary questions: which components exist, where information is stored, which external services participate, how each environment is configured and what path an important action follows.

In maintainable software, those answers are distributed across architecture, code, tests, documentation and team knowledge. In an application built solely through conversation, there may be no reliable source. The first task is therefore to reconstruct one.

This is not purely technical work. We also need to clarify which behaviour matters to the user and which data cannot be lost. An application is not fixed merely because the visible error has disappeared; it is fixed when we understand what it must preserve and can verify it.

From a patch to a quality system

A responsible recovery usually needs several layers:

  1. Create a reproducible way to run the project.
  2. Inventory dependencies, credentials, data and external services.
  3. Identify critical user journeys.
  4. Add tests around behaviour that must not break.
  5. Correct the structural risks that prevent further learning first.
  6. Leave instructions so the next change does not start from zero again.

AI can help at every step: exploring the repository, explaining fragments, proposing tests or locating inconsistencies. But our relationship with it has to change. We no longer ask, “Make it work.” We provide context, criteria and mechanisms for demonstrating what it has done.

Vibe coding is not a moral category

Creating through conversation can be an excellent way to explore an idea, learn or produce a prototype. The problem appears when an exploratory piece enters production without a corresponding change in discipline.

A prototype can assume fictional data, happy paths and reversible decisions. A product has to coexist with errors, permissions, updates, new people and real consequences. The transition between them does not happen because we rename “demo” as “version one”.

Invisible debt

Technical debt is not simply ugly code. It is the difference between what the system appears to do and what we can explain, verify and change with confidence. Fast generation can hide that difference for a while because every new failure receives an immediate response.

Eventually, nobody knows whether the next repair will solve a problem or move the damage elsewhere. Recovering the product means making that relationship visible again.

Our analysis showed that the cause was a browser-specific rendering behaviour. The image sent for extraction was being compressed, losing enough quality to undermine the OCR result. That is difficult to spot without direct web-development experience. The application was an MVP and could be used after the fix. Before evolving into a production application under significant load, however, it would need refactoring and explicit preparation for concurrency, race conditions and other real operating conditions.

Sources and references