Last week, I watched Cursor generate a beautiful, well-structured Express middleware. Clean types, proper error handling, JSDoc comments — the works.
There was just one problem: it imported a package that doesn't exist on npm.
import { validateSchema } from 'express-json-validator'; // ❌ This package doesn't exist
No red squiggly. No ESLint warning. No TypeScript error (it was in a .js file). It passed code review because the name sounded right. It would have crashed in production the moment someone ran npm install.
This is what I call an AI hallucination — and it's just one of five failure modes I've been tracking across 10,000+ AI-generated pull requests.
The 5 Failure Modes ESLint Will Never Catch
1. 🔮 Hallucinated Imports
AI models generate import statements from their training data. Some of those packages existed once, some never did, and some are typosquatted traps.
import { createClient } from 'redis-async'; // Doesn't exist — should be 'redis'
import { parseJSON } from 'json-parse-safe'; // Doesn't exist
import { sanitize } from 'express-sanitizer-plus'; // Typosquat candidate
Why linters miss it: ESLint validates syntax, not registry existence. TypeScript only checks types if you have @types installed (which you can't install for a package that doesn't exist).
2. 📅 Stale APIs
AI models are trained on code from 2021-2023. They confidently use APIs that have been deprecated or removed.
// Copilot still generates this in 2026:
const parsed = url.parse(req.url); // Deprecated since Node 11
const buf = new Buffer(data); // Removed in Node 20
app.del('/resource', handler); // Removed in Express 5
Why linters miss it: ESLint can flag some Node.js deprecations, but can't track every library's breaking changes across versions.
3. 🧩 Context Window Artifacts
When AI generates code across multiple files, it can create logical contradictions. File A expects a function signature that file B doesn't provide.
// user-service.ts (AI-generated)
export function getUser(id: string): Promise<User> { ... }
// auth-middleware.ts (AI-generated separately)
const user = await getUser(id, { includeRoles: true }); // ❌ Wrong signature
Why linters miss it: TypeScript would catch this if both files are in the same compilation. But in large monorepos with partial builds, this slips through.
4. 🏗️ Over-Engineered Patterns
AI loves abstraction. It generates factory-factory patterns, unnecessary generics, and dead code paths that add complexity without value.
// AI-generated: A factory that creates a factory that creates a validator
const createValidatorFactory = <T extends BaseValidator>(
config: ValidatorConfig<T>
) => (schema: Schema) => (data: unknown): ValidationResult<T> => {
// 47 lines of code to validate an email
};
Why linters miss it: ESLint's complexity rules (max-depth, complexity) are too coarse. They can't distinguish "necessarily complex" from "AI showing off."
5. 🔓 Security Anti-Patterns
AI generates code with hardcoded secrets from training examples, disabled TLS verification, and eval() calls.
const API_KEY = 'sk-proj-abc123def456'; // Hardcoded from training data
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // TLS disabled
const result = eval(userInput); // Code injection
Why linters miss it: ESLint's no-eval catches the obvious case, but AI generates creative variants (new Function(), vm.runInNewContext()) that slip through.
What I Built: Open Code Review
I spent 6 months building a CI/CD quality gate specifically designed for these AI-generated failure modes.
Open Code Review is:
- 🆓 Free forever — open source, MIT licensed
- 🏠 Self-hostable — runs 100% locally, no data leaves your machine
- ⚡ Fast — under 10 seconds for L1 scans
- 🔌 CI-native — GitHub Actions, GitLab CI, or any CI
How It Works
L1: Pattern Detection (fast, local, free)
├── Hallucinated import detection (npm/PyPI registry check)
├── Deprecated API detection (AST-based)
├── Security anti-pattern matching
├── Over-engineering heuristics
├── Code duplication analysis
└── Score: 0-100 with letter grade
L2: AI Deep Analysis (Embedding + LLM)
├── Embedding recall → risk scoring → Top-N suspicious blocks
├── LLM analysis (Ollama local or OpenAI/Anthropic cloud)
├── Cross-file context coherence
├── Semantic duplication detection
└── Enhanced scoring with AI confidence
30-Second Setup
# Install
npm install -g @opencodereview/cli
# Scan your project
ocr scan src/ --sla L1
# Add to GitHub Actions
# .github/workflows/code-review.yml
- uses: raye-deng/open-code-review@v1
with:
sla: L1
threshold: 60
scan-mode: diff
github-token: ${{ secrets.GITHUB_TOKEN }}
Real Results
OCR scans itself. Here's what it found:
╔══════════════════════════════════════════════════════════════╗
║ Open Code Review V4 — Quality Report ║
╚══════════════════════════════════════════════════════════════╝
📊 112 issues found in 110 files
Overall Score: 67/100 🟠 D
AI Faithfulness ████████████████████ 35/35 (100%)
Code Freshness ████████████░░░░░░░░ 15/25 (60%)
Context Coherence █████████████████░░░ 17/20 (85%)
Compared to Alternatives
| Open Code Review | CodeRabbit | GitHub Copilot | |
|---|---|---|---|
| Price | Free | $24/mo/seat | $10-39/mo |
| Open Source | ✅ | ❌ | ❌ |
| AI Hallucination Detection | ✅ | ❌ | ❌ |
| Self-hosted | ✅ | Enterprise | ❌ |
| Data Privacy | 100% local | Cloud | Cloud |
Try It
npm install -g @opencodereview/cli
ocr scan src/ --sla L1
⭐ Star on GitHub — it helps more developers discover this.
What AI code failure modes have you encountered? Drop a comment — I'm building new detectors based on community reports.
Top comments (1)
Missing one failure mode: AI-generated code that uses the right API but passes arguments in the wrong order when types are compatible (two string params swapped). TypeScript won't catch it and the code runs fine until edge cases surface in production.