AI generates a beautiful function. Clean code. Perfect logic.
One problem: it calls utils.formatCurrency() which doesn't exist in your codebase.
Or it uses axios.post(url, data, { retries: 3 }) when axios doesn't have a retries option.
Or it imports from @company/shared-utils which isn't a real package.
AI hallucinations in code generation are real, annoying, and costly.
Let's understand why they happen and how to minimize them.
What AI Hallucinations Look Like in Code
Invented Functions
// AI generates this
import { formatDate, parseDate, validateDate } from '@/utils/dateUtils';
const formatted = formatDate(date, 'YYYY-MM-DD');
Reality: Your dateUtils only exports formatDate. parseDate and validateDate don't exist.
Wrong API Signatures
// AI generates this
const response = await fetch(url, {
method: 'POST',
body: data,
timeout: 5000, // ← fetch doesn't have a timeout option
retries: 3, // ← this isn't a thing
});
AI confidently uses options that don't exist.
Phantom Libraries
// AI generates this
import { useQueryState } from 'next-query-state'; // ← not a real package
import { cn } from '@radix-ui/utils'; // ← doesn't exist
AI invents packages or confuses package exports.
Mixed API Versions
// AI generates this
const router = useRouter();
router.push('/dashboard', { scroll: false }); // Next.js App Router
router.query.id; // Next.js Pages Router - wrong API!
AI mixes APIs from different versions or paradigms.
Fictional Methods
// AI generates this
const users = await prisma.user.findManyWithRelations({
include: { posts: true }
});
The method is findMany, not findManyWithRelations. AI invented a more "logical" name.
Why AI Hallucinates Code
Training Data Conflicts
AI learned from millions of codebases with:
- Different library versions
- Different utility functions
- Different API patterns
- Different naming conventions
When generating code, it pattern-matches against this massive, conflicting dataset. Sometimes it matches the wrong pattern.
Confident Extrapolation
AI sees patterns and extrapolates:
- "There's
formatDate, so there's probablyparseDate" - "Most HTTP clients have
timeout, so fetch probably does too" - "This looks like a Prisma query, I'll use Prisma-like syntax"
It's making educated guesses—and sometimes they're wrong.
Context Limitations
AI doesn't have access to:
- Your actual node_modules
- Your utility functions
- Your API documentation
- Your codebase structure
It's generating code based on patterns, not reality.
Stale Knowledge
Libraries evolve. AI's training data might include:
- Old API signatures
- Deprecated methods
- Pre-release features that never shipped
- Changed behavior between versions
The Cost of Hallucinations
Debug Time
Hallucinated code often:
- Compiles without type errors (types might be
any) - Fails at runtime with cryptic errors
- Sends developers on wild goose chases
"Why isn't this working?" → Eventually → "Oh, this function doesn't exist"
Trust Erosion
Developers who get burned start:
- Distrusting all AI-generated code
- Manually verifying everything
- Avoiding AI for anything important
The productivity promise of AI erodes.
Subtle Bugs
Sometimes hallucinations partially work:
- A function exists but with different behavior than AI expected
- An API option is ignored rather than erroring
- A close-enough method produces slightly wrong results
These are harder to catch than complete failures.
Strategies to Reduce Hallucinations
1. Provide Context About Your Codebase
The less AI guesses, the fewer hallucinations. Tell it what exists:
# Available Utilities
## Date Utilities (src/utils/date.ts)
- formatDate(date: Date, format: string): string
- isValidDate(value: unknown): boolean
That's all. No parseDate, no validateDate.
## HTTP Client (src/lib/api.ts)
We use a custom API client, not raw fetch:
- api.get<T>(url: string): Promise<T>
- api.post<T>(url: string, data: unknown): Promise<T>
Don't use fetch directly. Don't invent options.
2. Specify Exact Versions and APIs
# Technology Versions
- Next.js 14 (App Router only, NOT Pages Router)
- Prisma 5.x (use current API, not deprecated methods)
- React 18 (hooks only, no class components)
- TypeScript 5.x (strict mode)
When unsure about an API, use the simplest known-working version.
Don't guess at options or parameters.
3. Instruct AI to Acknowledge Uncertainty
# When Unsure
If you're not certain a function/method/option exists:
1. Say so explicitly
2. Provide the most conservative implementation
3. Add a comment marking the uncertainty
Example:
// Note: Verify validateEmail exists in utils before using
const isValid = validateEmail(input); // May need implementation
Don't confidently generate code for APIs you're uncertain about.
4. Provide Real Examples
Show AI actual code from your codebase:
# Patterns From Our Codebase
## How we make API calls:
// Correct pattern from src/services/userService.ts
async function fetchUser(id: string): Promise<User> {
return api.get<User>(`/users/${id}`);
}
## How we handle errors:
// Correct pattern from src/services/baseService.ts
try {
const result = await api.get<T>(url);
return result;
} catch (error) {
logger.error('API call failed', { url, error });
throw new ApiError('Request failed', { cause: error });
}
Use EXACTLY these patterns. Don't invent variations.
5. List What NOT to Use
Explicit "don'ts" reduce hallucinations:
# Don't Use These
## Fake/Non-existent
- Don't import from '@/utils/validators' (doesn't exist)
- Don't use 'formatCurrency' (we don't have this)
- Don't use fetch's 'timeout' option (not real)
## Wrong Version
- Don't use useRouter().query (Pages Router - we use App Router)
- Don't use getServerSideProps (Pages Router - we use Server Components)
- Don't use Prisma's deprecated methods
## Not Our Pattern
- Don't use raw fetch (use our api client)
- Don't use console.log (use logger)
- Don't use raw Error (use AppError)
The SuperClawd Approach
SuperClawd lets you provide all this context automatically on every AI interaction.
Create Anti-Hallucination Skills
Skill: Our Utilities
# Available Utility Functions
## Date Utils (src/utils/date.ts)
Exports:
- formatDate(date: Date, format: string): string
- isToday(date: Date): boolean
- daysBetween(start: Date, end: Date): number
NOT available (don't use):
- parseDate (use new Date() or date-fns)
- validateDate (use isValid from date-fns)
## String Utils (src/utils/string.ts)
Exports:
- truncate(str: string, length: number): string
- slugify(str: string): string
NOT available (don't use):
- capitalize (use CSS text-transform)
- formatCurrency (use Intl.NumberFormat directly)
Skill: API Patterns
# HTTP Client Usage
## Use our API client, not fetch
import { api } from '@/lib/api';
// Correct
const user = await api.get<User>('/users/123');
const created = await api.post<User>('/users', userData);
// Wrong - don't use fetch
const response = await fetch('/api/users/123');
## Available methods
- api.get<T>(url): Promise<T>
- api.post<T>(url, data): Promise<T>
- api.put<T>(url, data): Promise<T>
- api.delete(url): Promise<void>
## Not available
- api.patch (use put)
- options like timeout, retries (handled at client level)
- interceptors (configured globally, don't add per-request)
Skill: Technology Constraints
# Version-Specific Rules
## Next.js 14 - App Router Only
Correct:
- useRouter from 'next/navigation'
- useSearchParams()
- Server Components with async
- route.ts for API routes
Wrong (Pages Router - don't use):
- useRouter from 'next/router'
- router.query
- getServerSideProps / getStaticProps
- pages/api/ directory
## Prisma 5.x
Correct:
- prisma.user.findUnique()
- prisma.user.findMany()
- prisma.user.create()
Wrong (don't exist):
- prisma.user.findManyWithRelations()
- prisma.user.upsertMany()
- prisma.user.softDelete()
Automatic Application
These skills apply to every AI interaction:
- When AI generates code, it knows what utilities exist
- When AI makes API calls, it uses your client correctly
- When AI uses frameworks, it uses the right version's API
No hallucinated functions. No invented options. No version mixing.
Testing for Hallucinations
Even with good instructions, verify AI output:
Quick Checks
- Hover imports in IDE - Do they resolve?
- Check autocomplete - Does the method show up?
- Run TypeScript - Type errors often catch hallucinations
- Simple runtime test - Does basic usage work?
Create a Hallucination Checklist
For AI-generated code, verify:
- All imports resolve
- All functions called exist
- API signatures match documentation
- No deprecated methods used
- Options/parameters are valid
Track Patterns
Keep notes on what AI hallucinates:
- Which utilities does it invent?
- Which APIs does it get wrong?
- Which versions does it confuse?
Add these to your skills as explicit "don't use" instructions.
Reducing Hallucinations Over Time
Week 1: Identify
Track hallucinations as you encounter them:
- What function was invented?
- What API was wrong?
- What should have been used?
Week 2: Document
Create skills with:
- What actually exists
- What doesn't exist
- Correct patterns with examples
Week 3: Deploy
Add skills to SuperClawd. Team uses automatically.
Ongoing: Refine
When new hallucinations appear:
- Add to "don't use" lists
- Clarify confusing APIs
- Add more examples
Hallucinations decrease as your documentation improves.
The Reality
AI hallucinations won't go to zero. AI is probabilistic, and code generation is hard.
But you can dramatically reduce hallucinations by:
- Providing context about your actual codebase
- Being explicit about what exists and what doesn't
- Giving real examples to follow
- Listing common mistakes to avoid
SuperClawd makes this automatic. Instead of hoping developers include the right context, your skills ensure every AI interaction has the information needed to generate real, working code.
Ready to reduce AI hallucinations in your codebase? Get started with SuperClawd and create skills that ground AI in your reality.
Use code WELCOME for free credits when you sign up!