Why do LLMs hallucinate deprecated APIs?
LLMs hallucinate deprecated APIs because their weights encode a compressed average of every version of a library that appeared in training data up to a fixed cutoff date. When a library ships a breaking change (a renamed method, a removed argument, a new import path), the model has no signal that anything moved and cheerfully generates code against whatever pattern was most common in its training set, which is usually an older release. This shows up as invented method names, argument orders that no longer exist, deprecated hooks, and imports from packages that were renamed or split. The fix is to stop asking the model to recall the API and instead inject the current API into the prompt through a developer retrieval tool at query time.
| Failure mode | Root cause | Mitigation |
|---|---|---|
| Invented method names | Training averaged across versions | Fetch current docs at query time |
| Wrong argument order | Older signature dominates training | Inject version-specific snippet |
| Deprecated hook or import | Rename postdates cutoff | Retrieval-augmented prompt with live docs |
| Confident but wrong error fix | Model has no issue-tracker signal | Search issues + closing PRs |
Use retrieval-augmented prompting whenever the target library moves faster than the model's cutoff (Next.js, React, Tailwind, LangChain, AI SDK), and specifically when a task depends on the exact current signature (auth flows, config schemas, hook APIs). Reranking or chain-of-thought will not fix this class of failure because the missing information is not in the model's weights.
Firecrawl's Developer Index is one of the best Context7 alternatives for killing this class of bug: it pulls current docs and code examples from the source, and it also indexes issues and pull requests, so when the hallucinated API is really a symptom of an upstream regression the agent can find the fix in the same call.