# Why Claude Code Invents Functions Your Codebase Doesn't Have


URL: https://getunblocked.com/blog/why-claude-code-invents-functions/
Published: 2026-08-12T15:00:00Z
Author: Dennis Pilarinos
Categories: AI Agents, Context Engine

Claude Code predicts plausible method names instead of your real API. 2026 research puts hallucinated references at 4.62-6.10% even on frontier models.

---
Claude Code invents functions because it predicts the most plausible API name from patterns in its training data, not from an index of your actual code. You watched it happen this morning. You asked the agent to add rate limiting to password resets, and the diff came back clean: `const user = await User.findByEmail(email)`, wrapped in a sensible guard clause, with a test that mocks the same method. It reads idiomatically. It sails into the PR. Then your reviewer leaves a single comment: `findByEmail` doesn't exist. Your codebase has `getUserByEmail`, defined in `users/repository.ts` and called from fourteen places, and nothing named `findByEmail` has ever been merged into your repo. The agent didn't misread your code. It never read the relevant file at all, and it filled the gap with the name most other codebases would use.

## Why does Claude Code call functions that don't exist in my codebase?

Three causes stack up to produce an invented method call.

First, interpolation. `findByEmail` is the dominant convention in the Rails, Spring Data, and Mongoose code the model trained on. When Claude Code needs a user-lookup method and your real signature isn't in front of it, it emits the statistically likely name. Engineers on r/ClaudeAI describe this pattern constantly: the agent references files, functions, and code that don't exist anywhere in the project.

Second, partial visibility. Claude Code doesn't hold your repository in memory; it greps and reads files on demand. If it never opened `users/repository.ts` this session, your actual signature was never in its context window, and prediction is all it has left.

Third, convention drift. Your internal APIs are by definition rare or absent in training data, and fabrication concentrates exactly where the model has seen a name least often. A 2026 re-evaluation of frontier models found five different models inventing [127 identical package names](https://arxiv.org/abs/2605.17062). That is what systematic interpolation looks like: the same wrong answer, reproduced deterministically, by models trained separately.

## How often do coding agents invent APIs?

The cleanest 2026 numbers come from package hallucination, because a package's existence can be checked against a registry. A May 2026 study re-evaluated five frontier models, including Claude Sonnet 4.6 and Claude Haiku 4.5, on [199,845 Python and JavaScript prompts](https://arxiv.org/abs/2605.17062) and found that between 4.62% and 6.10% of generations referenced packages that don't exist. Newer models shrank the range, but nobody got near zero, and 127 fabricated names were shared across all five models. The overlap matters more than the rate: the failure comes from how these models generalize, and no single vendor is going to patch it away.

Developers feel this. Stack Overflow's [February 2026 analysis](https://stackoverflow.blog/2026/02/18/closing-the-developer-ai-trust-gap/) of its survey data shows adoption and confidence moving in opposite directions: over 84% of developers use or plan to use AI tools, while only 29% say they trust AI, down 11 points year over year.

Internal-API invention is the same mechanism pointed at your codebase, with one difference. When a model invents a package, `npm install` fails loudly. When it invents `findByEmail`, nothing fails until the type checker, the reviewer, or production.

## What does an invented function look like in the wild?

Reports of Claude Code hallucinations converge on the same shape: confident code, plausible name, missing referent. In January 2026, a developer documented Claude generating file-upload code around a Prisma method called `$upload`. The generated code was confident and tidy; the runtime verdict was [`TypeError: prisma.$upload is not a function`](https://31daysofvibecoding.com/2026/01/14/when-ai-hallucinates/). Prisma has no `$upload` method. The model invented it whole.

Claude Code's own issue tracker shows the family of failures: users report the agent [pausing long-running tasks over hallucinated missing dependencies](https://github.com/anthropics/claude-code/issues/56690) and [making unverified assumptions instead of checking actual state](https://github.com/anthropics/claude-code/issues/36810).

Then there's the security tail. Invented names are so consistent that attackers pre-register them. In January 2026, Aikido Security claimed the npm name `react-codeshift`, a package that never existed but that [237 GitHub repositories were already instructing agents to install](https://www.aikido.dev/blog/agent-skills-spreading-hallucinated-npx-commands). By July, researchers demonstrated ["HalluSquatting" attacks](https://thehackernews.com/2026/07/new-hallusquatting-attack-could-trick.html) that plant malware behind reliably fabricated repository names, with success rates up to 85%. If invention were random noise, none of this would work.

## Does CLAUDE.md stop Claude Code from making up methods?

Partially, and it's worth doing. CLAUDE.md files give the agent [persistent instructions loaded at session start](https://code.claude.com/docs/en/memory), so conventions you write down ("user lookups live in `users/repository.ts`; never invent repository methods") survive across conversations.

What they can't do is close the gap. A mid-size repo has thousands of exported symbols, and the set changes with every merged PR, so any rules file that enumerates your API surface is stale by Friday. Nobody maintains a hand-written index of their own code, and CLAUDE.md quietly asks you to. Rules are instructions, not retrieval: when the real signature isn't in context, the model still produces method names by prediction, and Anthropic's own docs are explicit that CLAUDE.md content is context the model tries to follow rather than enforced configuration. Long rules files also pay a context tax every session; the same docs recommend keeping them under 200 lines, which rules out documenting your API there. None of this is CLAUDE.md's fault: [Claude Code doesn't retain your codebase shape between sessions](https://getunblocked.com/blog/claude-code-forgets-codebase/), so instructions end up doing a job that only [retrieval infrastructure can do](https://getunblocked.com/blog/rules-files-vs-context-engine/).

## Can you just paste more of the repo into the context window?

This is the other folk remedy, and it helps less than it looks like it should.

Scope: pasting `users/repository.ts` grounds the agent in exactly that file, for exactly this session. The next invented call will come from a module you didn't paste, and tomorrow's session starts from zero.

Attention: a repo stuffed into the window still gets skimmed, and a signature the model glossed over might as well not be there. Bigger windows raise the ceiling without changing the behavior, because attending to a million tokens is not the same as looking one symbol up.

Staleness: the repo mutates under you. Yesterday's paste contains yesterday's signatures, and an agent grounded in last week's snapshot will confidently write calls against methods your team renamed on Tuesday. [Cursor has its own version of this failure](https://getunblocked.com/blog/why-cursor-hallucinates-and-forgets-context/), where the same context limits show up as forgetting rather than inventing. Same underlying gap: the agent has a sliver of your code when it needs an index of it.

## What actually grounds an agent in the code you have?

Retrieval of what actually exists, at the moment the agent is about to write the call: the real signature, the real call sites, and the convention your team settled on. 2026 research converges here. A January 2026 framework parses generated code and validates every reference against a knowledge base built from the actual libraries in use, catching non-existent APIs with [100% precision and 87.6% recall, and auto-correcting 77% of them](https://arxiv.org/abs/2601.19106). The principle generalizes: check generation against ground truth instead of hoping prediction lands.

That's the job Unblocked does for coding agents: it grounds them in what actually exists. It's the context engine coding agents query before they write, and it surfaces real signatures, call sites, and team conventions at the moment of need, along with the decisions behind them from PRs, docs, and chat. When the agent asks what the user-lookup method is called, it gets back `getUserByEmail`, the file it lives in, and the discussion where the team standardized on it, instead of a statistically popular guess.

> My setup tells the agent: before you implement anything, go check Unblocked. It has everything — our repos, Notion, Slack, coding standards — and it surfaces things I wouldn't have thought to look for. GitHub Copilot doesn't have any of that organizational context. I'd rate the impact an eight or nine out of ten, and it's only gotten better.
>
> — Justin McCraw, Software Engineer, The Information


Grounding also raises the question of precedence when sources disagree, which is [its own problem: which source of truth should the agent trust](https://getunblocked.com/blog/coding-agent-source-of-truth/).

## Making the inventions stop

Three concrete moves, in order of cheapness:

1. **Make "does this symbol exist?" a hard gate.** A grep or a typecheck in the loop, before the diff lands, catches most invented calls for pennies. If your language has a compiler, run it; if it doesn't, a symbol-existence check in CI is the next best thing.
2. **Audit your CLAUDE.md for retrieval problems wearing rule costumes.** Every line shaped like "use `getUserByEmail`, not `findByEmail`" is a patch over a lookup the agent should be doing itself. Keep the conventions; stop trying to enumerate the API surface.
3. **Give the agent a query path to what exists.** Signatures, call sites, decisions. An agent that can ask before it writes has no reason to guess, and an agent that can only predict will keep predicting.

The inventions are what generation without grounding looks like, and the next model release won't fix that.

## Frequently asked questions

### Why does Claude Code make up functions?

Because it generates the most plausible method name from patterns in its training data rather than looking up your actual API. When the real signature isn't in its context window, ecosystem-wide conventions fill the gap, which is why the invented names (like `findByEmail`) sound so reasonable.

### How do I stop my coding agent inventing methods?

Put a symbol-existence check (typecheck, grep, or compile) in the loop before any diff lands, and give the agent retrieval access to your real signatures and call sites so it queries instead of guessing. Rules files help at the margins but don't do retrieval.

### Does CLAUDE.md stop hallucinations?

It reduces them for the conventions you thought to write down. It can't cover thousands of exported symbols that change every PR, and instructions don't substitute for retrieval: the model still predicts names when the real one isn't in context.

### Is calling a deprecated API the same as inventing one?

No. A deprecated API is [old but real](https://getunblocked.com/blog/ai-agent-deprecated-api/): it existed, and the agent's knowledge is out of date. An invented API never existed anywhere. One is a freshness problem, the other a grounding problem, and they need different fixes.

### Does this happen more in big codebases and monorepos?

Yes. Large codebases carry more internal conventions that diverge from open-source norms, and less of their API surface resembles anything in training data. More symbols, more drift, more room for a plausible-but-wrong name. Which is also where symbol checks and grounded retrieval pay off most.