the IT Hustle
工具实战手册关于
AI CriticismAI辅助2026-03-18•13 min 阅读

What AI Gets Wrong About Code Generation

作者: Salty Deprecated Software Engineer

✨ AI 辅助内容

本文由 AI 辅助创作,并经团队审核以确保准确性和质量。所有技术信息和示例均已验证。

I use AI code generation every day. GitHub Copilot is open in my editor right now. I've used Claude, ChatGPT, and Gemini to write production code. I'm not an AI skeptic.

But I've also shipped AI-generated code that contained a critical security vulnerability. I've wasted hours debugging functions that "looked right" but weren't. And I've watched junior developers blindly accept suggestions that would have caused data loss in production.

The problem isn't that AI code generation is bad. It's that the industry is treating it as a replacement for understanding, when it's actually a tool that requires more understanding to use safely. AI generates code that passes the "looks reasonable" test but frequently fails the "actually works correctly in all cases" test.

This article is a field report from someone who uses AI code generation daily and has catalogued its failure modes. If you're an experienced developer, this will help you build a mental model for when to trust AI output and when to be skeptical. If you manage developers, this will help you understand why "we used AI to write it" is not a quality guarantee.

The Fundamental Problem: Pattern Matching vs. Understanding

AI code generation works by pattern matching against its training data. It has seen millions of code examples and learned statistical relationships between code patterns. When you ask it to write a function, it's essentially asking: "What code patterns typically follow this prompt?"

This is fundamentally different from how humans write code. A human developer considers the specific requirements, edge cases, performance constraints, security implications, and how this code interacts with the rest of the system. The AI considers none of these things. It produces the most statistically likely code given the prompt.

The result: AI-generated code is optimized for "looks correct" rather than "is correct." And those are very different things.

Failure Mode #1: Hallucinated APIs and Methods

This is the most common failure and the easiest to demonstrate. AI models confidently use functions, methods, and API endpoints that don't exist.

AI-generated Node.js code:

const fs = require('fs');

const content = fs.readFileAsync('data.txt', 'utf8');

// ❌ fs.readFileAsync doesn't exist in Node.js

What it should be:

const fs = require('fs').promises;

const content = await fs.readFile('data.txt', 'utf8');

The AI mixed up naming conventions from different libraries. readFileAsyncsounds plausible — it follows the "Async" suffix pattern common in C# and some npm packages — but it doesn't exist in Node's standard library. This will crash at runtime, not at compile time, which means it might make it through a cursory code review.

Another common hallucination — React hooks that don't exist:

const prevState = usePrevious(count);

// ❌ usePrevious is NOT a built-in React hook

AI also frequently suggests:

useEvent() // ❌ proposed RFC, never shipped

useEffectEvent() // ❌ experimental, not stable

useOptimistic() // ⚠️ exists in React 19+ only

The pattern here is clear: AI models are trained on blog posts, tutorials, RFC proposals, and experimental code alongside stable APIs.They can't distinguish between a function that was proposed, discussed, and rejected versus one that shipped in a stable release.

Failure Mode #2: Security Vulnerabilities

This is where AI code generation gets genuinely dangerous. Security isn't about making code work — it's about preventing code from being exploited. AI is optimized for the former, not the latter.

AI-generated SQL query (SQL injection vulnerability):

app.get('/users', (req, res) => {

const query = `SELECT * FROM users WHERE name = '${req.query.name}'`;

db.query(query);

});

Correct (parameterized query):

app.get('/users', (req, res) => {

db.query('SELECT * FROM users WHERE name = $1', [req.query.name]);

});

I've personally seen AI generate SQL injection vulnerabilities, XSS-vulnerable HTML rendering, path traversal in file operations, and hardcoded secrets in source code. The AI doesn't generate these maliciously — it simply pattern-matches from its training data, which includes millions of insecure code examples from tutorials and Stack Overflow answers.

AI-generated auth check (broken authorization):

app.get('/admin/users', (req, res) => {

if (req.headers.role === 'admin') {

// ❌ Checking a client-sent header for authorization!

return res.json(await getUsers());

}

});

Anyone can set any HTTP header — this is not authorization.

The fundamental issue: security is about adversarial thinking. AI is trained on cooperative, educational content.It doesn't think about how an attacker would exploit the code it writes. It generates the "happy path" and leaves the attack surface wide open.

Failure Mode #3: Outdated Patterns and Deprecated APIs

AI training data has a cutoff date, and even within that window, the model has seen far more old code than new code. The internet has 15 years of jQuery tutorials and 2 years of React Server Components docs. Guess which patterns the AI reaches for?

AI frequently suggests:

componentWillMount() // ❌ deprecated in React 16.3 (2018)

new Buffer('data') // ❌ deprecated in Node 6 (2016)

request('url', cb) // ❌ request npm package deprecated (2020)

moment().format() // ❌ Moment.js in maintenance mode (2020)

This problem is particularly insidious because deprecated code usually still works. Your tests pass. Your app runs. But you're building on top of patterns that the community has moved away from for good reasons — security issues, performance problems, or better alternatives.

Failure Mode #4: The "Looks Right But Isn't" Problem

This is the most dangerous failure mode because it requires deep domain knowledge to catch. The code compiles. Tests might even pass. But the logic is subtly wrong.

AI-generated debounce function:

function debounce(fn, delay) {

let timer;

return function(...args) {

clearTimeout(timer);

timer = setTimeout(() => fn(...args), delay);

};

}

This looks correct and works for most cases. But it has a subtle bug: this context is lost because the inner function uses an arrow function for setTimeout but a regular function for the return. In a class component or object method, this inside fnwon't refer to what you expect. The fix:

Correct (preserves this context):

function debounce(fn, delay) {

let timer;

return function(...args) {

clearTimeout(timer);

timer = setTimeout(() => fn.apply(this, args), delay);

};

}

Failure Mode #5: Missing Error Handling

AI consistently generates the "happy path" — what happens when everything goes right. It rarely generates proper error handling, retry logic, timeout management, or graceful degradation.

AI-generated API call:

const response = await fetch('/api/data');

const data = await response.json();

What production code needs:

try {

const controller = new AbortController();

const timeout = setTimeout(() => controller.abort(), 5000);

const response = await fetch('/api/data', {

signal: controller.signal

});

clearTimeout(timeout);

if (!response.ok) {

throw new Error(`HTTP ${response.status}`);

}

const data = await response.json();

} catch (err) {

if (err.name === 'AbortError') // handle timeout

// handle network errors, parse errors, HTTP errors

}

The AI-generated version has no timeout, no status code checking, no error handling, and no abort controller. In a tutorial, this is fine. In production, this will hang indefinitely when the API is down, crash when the response isn't JSON, and silently accept error responses as valid data.

Failure Mode #6: Lack of Context Awareness

AI generates code in isolation. It doesn't know about your application's architecture, your team's conventions, your performance requirements, or the other code in your codebase.

  • It doesn't know your codebase already has a utility for that. AI will happily generate a new date formatting function when your project already has one. Now you have two, and they behave slightly differently.
  • It doesn't understand your performance constraints. AI might suggest loading an entire 50MB dataset into memory when your application runs in a serverless function with 128MB of RAM.
  • It doesn't follow your team's patterns. Your team uses dependency injection and the AI generates tightly coupled code. Your team uses functional components and the AI generates class components. Your team uses Zod for validation and the AI uses Joi.
  • It doesn't consider the deployment environment. Code that works perfectly in development can fail in Docker, Lambda, or Edge Functions due to filesystem access, environment variables, or cold start constraints.

When AI Code Generation Works Well

Let's be fair. AI code generation is genuinely useful in specific scenarios:

  • Boilerplate and scaffolding. Generating React component shells, Express route handlers, TypeScript interfaces from examples. Code that follows well-established patterns with minimal logic.
  • Test generation. AI is surprisingly good at generating unit tests for existing code. It sees the function, understands the expected behavior, and writes assertions. Still needs review, but it's a huge time saver.
  • Documentation and comments. Generating JSDoc comments, README sections, and inline documentation from existing code. The AI can describe what code does; it struggles more with writing code that does what it should.
  • Learning and exploration. Asking "show me how to use the Streams API in Node.js" and getting a working example you can study and modify. Use it as a starting point, not a final answer.
  • Regex and complex string operations. Ironically, AI is decent at generating regex patterns — as long as you test them thoroughly against edge cases.

A Practical Framework: When to Trust AI Code

Here's the mental model I use daily:

  • High trust: Boilerplate, scaffolding, simple CRUD operations, TypeScript types, CSS, documentation, well-established patterns (sorting, filtering, mapping).
  • Medium trust (verify carefully): Business logic, data transformations, API integrations, database queries, error handling, validation logic.
  • Low trust (treat as pseudocode): Authentication, authorization, encryption, payment processing, data migration, concurrency, anything security-related.

The rule is simple: the higher the consequences of a bug, the less you should trust AI-generated code. A wrong CSS color is harmless. A wrong authentication check is catastrophic.

Key Takeaways

  • AI generates code optimized for "looks correct," not "is correct." Always verify, especially for edge cases and error handling.
  • Hallucinated APIs are real and frequent. Always verify that functions, methods, and endpoints exist in the version you're using.
  • Security is the biggest blind spot. AI generates happy-path code. It doesn't think about attackers, injection, or authorization bypasses.
  • Outdated patterns sneak in constantly. AI has seen more old code than new code. Verify that suggestions use current best practices.
  • Context awareness is nonexistent. AI doesn't know your architecture, conventions, or constraints. You have to provide that context yourself.
  • Use AI for boilerplate, not business logic. The higher the stakes, the less you should trust AI-generated code without thorough review.

AI code generation is a powerful tool — but only in the hands of someone who understands the code it produces. Build your fundamentals first, then use AI to accelerate. Need to clean up text, compare outputs, or format AI-generated content? Try our free Text Tools suite.

IT
Salty Deprecated Software Engineer

以 The IT Hustle 的编辑笔名写作——25 年以上笔记本维修技师、系统管理员、存储工程师和软件工程师的经验,如今用在 AI 智能体运维上。每篇文章发布前都经过人工审核,详见编辑准则。

我们的工具全部文章关于我们

获取最新资讯

第一时间了解新工具、博客文章和更新动态。无垃圾邮件。

生成专属防幻觉提示词

AI 提示词引擎采用专有技术,生成内置验证和矛盾测试的提示词。

免费试用 3 次 →

公司

  • 关于
  • 实战手册
  • AI 术语表
  • 关于作者
  • 联系我们

产品

  • 工具
  • 价格观察
  • 智能体运维
  • 编程
  • 设计
  • 运维
  • 效率
  • 营销
  • 商务

法律信息

  • 隐私政策
  • 服务条款
  • 免责声明
  • 编辑准则
  • 更正说明

© 2026 Salty Rantz LLC. 版权所有。

为在技术变革中前行的职场人打造。