Understanding Software vs. Generating Code

State bugs and flow control in real applications highlight the gap between someone who understands software and someone who merely generates code.

AI models have evolved drastically.

Today they write boilerplate, suggest architectures, generate tests, explain APIs, and accelerate a massive amount of work.

Yet there is a specific type of problem where the gap between someone who truly understands programming and someone who merely generates code becomes glaringly obvious: state bugs and flow control in a real application.


The Real Case: Full-Text Content Search in Flux

Over the past few days, I was implementing a new feature in Flux, my open-source file manager written in Rust.

The goal was to add full-text searching inside file contents directly in the search engine, rather than searching strictly by filename.

The implementation was almost ready. There was just one problem: after the second search, the application would simply freeze.

Handing the Entire Project to AI Models

I passed the whole codebase to the best AI models I could find: complete code, architecture diagrams, message flow, logs, and context.

Claude
ChatGPT
DeepSeek
Qwen

Even when I explained exactly where I suspected the issue was, all of them insisted on the same direction.

Their diagnosis insisted that the root cause was in:

AppMsg::StartContentSearch(term)
Diagnosis #1

"Maybe it's a synchronization issue."

Diagnosis #2

"There could be an execution deadlock between tasks."

Diagnosis #3

"Perhaps the event loop is causing an unexpected condition."

Diagnosis #4

"It might be thread management."

It all sounded plausible. But the problem was not there.

I kept explaining that the problematic flow was actually a different one:

AppMsg::UpdateFilter(query)

It was re-entering a path that caused an infinite loop. Even so, their answers kept returning to the exact same hypothesis.


Manual Investigation & The Fix

After much insistence, I had to close all the AI tools and go back to the code. I followed the application state by state.

The cause was simple: when the search opened, a filter update occurred again under a specific condition, and the flow lacked a guard for that case.

The fix required just a simple state guard:

State Flow Guard (Rust) Simple Guard
if query.is_empty() && self.search_just_opened {
    self.search_just_opened = false;
    return;
}

A state guard. Just that.

Then another bug appeared: when canceling a search, the routine properly cleared the file grid, but forgot to rebuild the UI state. The data was correct, but the screen never received the update event.

All that was missing was:

UI Update (Rust) UI Refresh
sender.input(AppMsg::Refresh);

Two small fixes. Two issues that completely halted the project.


What This Teaches About "Vibe Coding"

And this is precisely where the point about vibe coding comes in.

Generating code with AI is extremely powerful. I can develop much faster using these tools.

However, there is a huge difference between generating code and understanding software.

Generating Code with AI

Rapidly creates pattern-matched solutions, but lacks the deep understanding of intent or event chains in a live application.

Understanding Software

Knowing precisely how state, events, concurrency, and data flow behave when things deviate from the expected path.

When you don't know how an application works internally, a bug like this can completely stall your project. AI can generate a solution, but someone still needs to know when that solution actually makes sense.

Because in the end, it wasn't a complex architecture or a mysterious failure. It was a state entering the wrong flow, and a UI update that never happened.

"AI is a multiplier. But it primarily multiplies the capability of those who already know how to navigate code."