Skip to content
All posts

Vibe Coding Only Works If You Already Know How To Code

July 6, 2026·Read on Medium·

The model can generate syntax, scaffolding and even passing tests. It still cannot replace the judgment that decides whether the patch is safe.

A coding model can make you feel productive long before it makes you correct.

That is the trap.

You ask for a webhook endpoint, a billing retry job, or a feature flag rollout. The AI gives you a route, a controller, a migration, a test file, and a neat little summary that sounds like someone already thought things through. The code compiles. The tests pass. The diff is clean enough that your brain wants to stop working right there. If you already know how these systems fail, that moment is useful. If you do not, it is where the trouble starts.

That is why vibe coding only works if you already know how to code.

I do not mean “can write a for loop.” I mean the kind of knowing that lets you look at a patch and ask the annoying questions the model did not volunteer. What happens on retries? What owns idempotency? What state exists outside this one request, and which part of this diff is locally correct but globally unsafe? The people who get real advantage from coding agents are not the people who stopped thinking. They are the people whose thinking got more concentrated.

GitHub now documents vibe coding directly. The premise is simple: describe what you want, let the system build, then iterate. The major coding-agent vendors describe the same future from different angles. The tools can research a repository, create a plan, run tests, and prepare a branch faster than most humans will. OpenAI says users still need to manually review and validate agent-generated code before integration. Anthropic says decisions about what code ships remain with the human. The most important people in this market are telling you, in plain English, that the tool is not the final authority. You are.

That is not marketing caution. It is the whole mechanism.

The Illusion Is That Working Code Equals Good Code

Vibe coding feels magical because it solves the part of programming that looks most visible from the outside.

You see files appear, code compile, components render, and tests pass, which to a beginner looks a lot like mastery because most of software is still invisible until it breaks under real traffic, real users, or real constraints.

Experienced engineers know there are at least three different levels of “this works”:

  • it runs
  • it survives the obvious test case
  • it behaves correctly inside the full system you are actually operating

AI is already very good at the first two.

That matters, and it matters a lot because a model can save hours of setup work, repetitive edits, migration scaffolding, handler plumbing, and test boilerplate. GitHub’s own cloud agent documentation leans into exactly this: research the repository, build a plan, implement changes on a branch, run tests and iterate in the background. That is useful labor. Sometimes it is excellent labor.

But those are still not the same thing as system judgment.

The dangerous gap is not syntax. It is scope.

Models are good at completing a local pattern. Engineers are paid to see where the local pattern lies.

If your mental model of software is “good code is code that looks finished,” vibe coding will fool you. If your mental model is “good code is code that respects constraints outside the file,” vibe coding becomes much more valuable because you know what to inspect.

What Skilled Engineers Actually Contribute in an AI Session

People talk about coding agents as if the choice is between “AI wrote it” and “a human wrote it.” That is the wrong split. The real split is between code generation and engineering judgment.

When a strong engineer works with a coding model, they are usually doing four jobs the model is weak at unless the context is unusually tight.

1. They define the real boundary of the task

Beginners prompt for the visible feature.

Experienced engineers prompt for the real unit of change: request path, background job behavior, schema compatibility, observability, rollback surface, authorization, cache invalidation, support burden. They know the patch is never just the patch.

2. They reject locally correct but system-wrong code

The generated code may satisfy the ticket and still break the service.

That happens all the time with concurrency, auth edges, race conditions, retries, stale reads, migration order, and failure handling. A model can write a beautiful controller that quietly duplicates side effects or assumes a single request path in a system built on retries and queues. You need someone who recognizes the lie.

3. They know what the tests did not prove

This is the quietest difference between a junior engineer and a senior one in an AI-heavy workflow.

A beginner often treats generated tests as evidence that the implementation is safe. An experienced engineer reads the tests and asks what they failed to model: duplicate delivery, weird payload order, empty state, permission drift, timeout behavior, clock skew, dead-letter handling, and all the other nonsense that production keeps inventing because production has no interest in being elegant.

4. They know when to stop accepting output

This one sounds small, but it is not.

A lot of bad AI-assisted coding comes from emotional momentum. The model is moving and the diff is growing, so saying “no, back up, this should be redesigned” starts to feel wasteful because the tool already produced so much material, but good engineers kill the patch anyway. They are not impressed by volume. They are paying attention to correctness.

That is the actual pressure point. Coding agents turn keystrokes into a cheaper resource. They do not turn judgment into one.

A Small Example That Looks Fine Until It Doesn’t

Imagine you ask an AI tool to add a Laravel webhook endpoint for a partner system. The partner may retry deliveries. Your app should update order state and trigger downstream work once.

The model is very likely to give you something like this:

// Pseudocode only - verify against official docs before use.
public function handleWebhook(Request $request)
{
$order = Order::updateOrCreate(
['external_id' => $request->input('id')],
['status' => $request->input('status')]
);

DispatchShipment::dispatch($order->id);

return response()->json(['ok' => true]);
}

That looks reasonable because it is compact, uses framework patterns, and probably passes a happy-path test.

It also hides the real questions:

  • What prevents the same webhook from dispatching the shipment twice?
  • What happens if two retries land at nearly the same time?
  • What guarantees that status can move in this direction?
  • What records the raw event for replay or audit?
  • What happens if the database write succeeds and the job enqueue fails?

None of those questions are exotic. They are the job.

Now compare that with a smaller but more honest building block taken from Laravel’s documented atomic lock API:

use Illuminate\Support\Facades\Cache;

Cache::lock("partner-webhook:{$eventId}", 10)->block(5, function () use ($eventId) {
// Handle the event once while the lock is held.
});

That snippet does not solve the system. It does reveal the system.

The second version forces you to think about duplicate delivery, shared state, and concurrent execution. The first version hides those concerns behind a convenient abstraction. That is exactly why an experienced engineer gets more out of AI than a beginner does. The beginner sees a finished endpoint. The experienced engineer sees a missing control surface.

This is what I mean by “already know how to code.” It is not about typing syntax from memory. It is about seeing the invisible work around the code the model generated.

The Model Is Accelerating Your Judgment, Not Replacing It

OpenAI’s Codex launch page is unusually clear about this. The system can read and edit files, run test harnesses, linters and type checkers, and show terminal logs so users can verify what happened. Then it says the part many people want to skip: users still need to manually review and validate all agent-generated code before integration and execution.

Anthropic says the same thing in a different tone. Claude Code can run commands, fix code after test failures, and execute across a toolchain, but decisions about what ships remain with the human.

If the companies selling these tools refuse to pretend that generated code should merge itself, you should probably refuse too.

This matters because a lot of current AI discourse is built on the wrong unit of measurement. People compare coding speed while ignoring code acceptance quality. They compare lines produced while ignoring rollback cost. They compare demo output while ignoring who noticed the dangerous assumption before it hit production.

That is why some teams think AI transformed their output and others think it mostly increased review burden. They are measuring different bottlenecks.

If the team’s main bottleneck is repetitive implementation work, AI looks incredible.

If the team’s main bottleneck is system judgment, change risk, prioritization, or architectural discipline, AI mostly changes where the work piles up because you write less from scratch and spend more time defining the task precisely enough that a machine cannot wander into the wrong solution very quickly. You review more. You reject more.

That is still a productivity gain, by the way. It is just a different one.

The best framing I have found is this: AI makes the cheap part of coding cheaper. It does not make the expensive part disappear.

The Save-Worthy Test Before You Accept an AI Patch

If you want a practical rule, use this one.

Before you accept an AI-generated patch, answer these five questions without looking back at the model’s explanation:

  1. What system constraint is this patch assuming?
    If you cannot name the hidden assumption, you probably should not merge it.
  2. What side effect would hurt if it happened twice?
    Payment capture, email sends, shipment creation, quota consumption, retries, state transitions. Pick one and trace it.
  3. What would make this pass tests and still fail in production?
    This question alone separates feature completion from engineering.
  4. What part of the change is hardest to roll back?
    If the answer is data, jobs, or public API behavior, the patch needs more skepticism.
  5. What evidence would convince you the patch is safe?
    Not “the model sounded confident.” Real evidence: tests for the right edge, logs, constraints, metrics, staged rollout, or a simpler design.

If you cannot answer those questions, do not treat the output as finished code. Treat it as a draft produced by a very fast intern with perfect syntax and uneven judgment.

That is not an insult to the tools. It is the correct operating model.

Where Vibe Coding Actually Works Well

The title is intentionally sharp, but the point is not that non-engineers should stay away from coding tools forever.

Vibe coding works well in a few situations even when the user is not deeply technical:

  • prototypes where the cost of being wrong is low
  • internal tools with tight scope and patient users
  • one-off automations where failure is visible and reversible
  • learning environments where the code is a way to ask better questions

That is a real category of value. It is not fake. GitHub’s vibe coding tutorial exists because this mode of software creation is genuinely useful.

But usefulness and safety are not the same thing.

Once the software carries money, identity, permissions, retries, concurrency, migrations or third-party integrations, the value of the human shifts from “person who typed this” to “person who knows what can go wrong,” especially when the state outlives the current request. That is why experienced engineers get so much out of these tools. They know where the generated patch ends and the system begins.

The beginner sees acceleration. The expert sees attack surface, rollback surface, and maintenance surface too.

Both are looking at the same diff. Only one of them is really reviewing it.

The Real Skill AI Is Exposing

For years, a lot of engineering skill stayed hidden behind typing speed, framework fluency, and familiarity with boilerplate. AI is stripping some of that away.

Good.

Now the part that remains is easier to see: problem framing, failure modeling, task decomposition, review discipline, architectural taste, and the ability to tell when an answer is only cosmetically complete.

That is why the strongest engineers I know are not threatened by vibe coding. They are using it aggressively. They just are not confusing generated output with finished engineering work.

Vibe coding works best when the human in the loop already knows what good code is, what safe code is, and most importantly, how those two are not always the same thing.

That difference is the whole game now.

Found this helpful?

If this article saved you time or solved a problem, consider supporting — it helps keep the writing going.

Originally published on Medium.

View on Medium
Vibe Coding Only Works If You Already Know How To Code — Hafiq Iqmal — Hafiq Iqmal