DEV Community

Raye Deng
Raye Deng

Posted on • Originally published at codes.evallab.ai

ESLint can't catch this: 5 failure modes unique to AI-generated code (and how I detect them in CI)

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
};
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
- uses: raye-deng/open-code-review@v1
  with:
    sla: L1
    threshold: 60
    scan-mode: diff
    github-token: ${{ secrets.GITHUB_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

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%)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Star on GitHub — it helps more developers discover this.

📦 NPM | 🌐 Website | 📖 Docs


What AI code failure modes have you encountered? Drop a comment — I'm building new detectors based on community reports.

Top comments (1)

Collapse
 
klement_gunndu profile image
klement Gunndu

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.