Guides·27 July 2026·7 min read

How to catch AI-hallucinated code before it ships

Every engineer using an AI assistant has met the same failure: the code is fluent, idiomatic, passes a quick read — and it's wrong in a way that surfaces days later, somewhere else, under load. The industry calls it hallucinated code. It isn't rare, and it isn't going away as models get bigger; it just gets more plausible.

The four shapes hallucinated code takes

  • Invented APIs. A method that doesn't exist on the SDK version you're pinned to. It compiles in the assistant's head, not in your build.
  • Faked outcomes. A refund path that returns success without ever calling the payment provider. Reads like defensive coding; is actually a lie.
  • Mocks left in the wire path. Placeholder responses and stub data that were supposed to be temporary and are now one deploy away from production.
  • Claimed completion. “Done — tests pass, deployed.” Nothing was run. The assistant is pattern-matching what a finished task sounds like.

Notice what these have in common: none of them are style problems. A linter won't catch them. A second opinion from the same model usually won't either, because the reviewer inherits the blind spots of the generator.

Step 1 — separate reality checks from quality checks

The mistake most teams make is treating AI review as one pass. It needs two, in order:

  • Reality gates first, and they must be deterministic. Does the claimed API exist? Does the “successful” path actually perform the side effect? Are there mocks or placeholders in production code? Is anything claimed “done” that can't be proven? These are yes/no questions — any single failure should veto the output, no averaging.
  • Quality review second, only on what survives. Performance, scalability, failure modes, tech debt — scored against a published standard (ISO/IEC 25010 is the one we use), not vibes.
The ordering matters. If you blend reality and quality into one score, a beautifully structured function that fakes its refund path can still average out to “acceptable.” A veto architecture makes that impossible.

Step 2 — put the gate inside the assistant's loop, not after it

A gate that runs in CI catches problems after the assistant has already told you the work is finished — you pay the context-switch cost on every failure. The better place is inside the tool loop: the assistant calls the gate before presenting work, gets a verdict with specific findings, and fixes its own output while the context is still hot. The Model Context Protocol (MCP) makes this a config block rather than an integration project — the same gate then works in Claude Code, Cursor, Windsurf, or any MCP client.

Step 3 — demand verdicts with findings, not scores alone

A bare 6/10 teaches the assistant nothing. A useful gate returns the specific defect and the math: “N+1 synchronous API calls — 100 items ≈ 100 roundtrips, ~10–20 s, blocks the worker thread, trips the payment provider's rate limit.” That's a finding an assistant can actually act on — and an engineer can audit. When we run our own gate on a plausible-looking 12-line billing snippet, it comes back REJECTED — 30.8/100 with findings at that level of specificity. (The verbatim verdict is on our MCP page.)

What this looks like in practice

Once your account exists, the whole integration is one block in your MCP client config:

mcp config — Claude Code, Cursor, Windsurf, or any MCP client
{
  "mcpServers": {
    "verificate": {
      "url": "https://<gateway>/mcp",
      "transport": "http",
      "headers": { "Authorization": "Bearer <YOUR_TRIAL_TOKEN>" }
    }
  }
}

From then on the assistant has four tools available — validate_ai_output, analyze_code, validate_plan and generate_code — and a standing instruction is enough to make it gate every substantive change before claiming completion.

The bar to hold

Whatever tool you use, hold it to this: deterministic reality gates with veto power, an independent review standard, findings specific enough to audit, and a place inside the assistant's loop. That combination is what turns “the AI wrote it and it looked fine” into “the work survived a veto-empowered review.”

FAQ

What is hallucinated code?

Code an AI assistant generates that looks correct but references APIs, SDK methods, config keys or behaviours that don't exist — or that silently fakes an outcome, like a refund function that returns success without moving money. It compiles, reads well in a diff, and fails in production.

Why doesn't asking the same model to review its own code work?

Because the review inherits the same blind spots that produced the bug. A model that invented an SDK method will usually defend it on review. Reliable checking needs signals outside the generating model: deterministic gates, static analysis of what the code actually does, and independent review criteria.

How do I add a validation gate to Claude Code, Cursor or Windsurf?

Add an MCP (Model Context Protocol) server entry to your client config with the gate's URL and your token. The assistant then calls the gate's tools — for example validate_ai_output — before presenting work as done. Setup is a single JSON block and takes a few minutes.

Put a real gate on your AI output.

Verificate MCP runs deterministic reality gates plus an enterprise-grade review on every AI output — in Claude Code, Cursor, Windsurf or any MCP client. 30-day free trial, no card required.