Debugging AI-Generated Code

Reviewing AI-Generated Code

4 min read

AI-generated code requires careful review before deployment. This lesson teaches systematic review techniques to catch issues early.

The Review Mindset

Trust but verify:
├── AI makes mistakes
├── Context can be misunderstood
├── Edge cases are often missed
├── Security requires human judgment
└── Performance implications need review

Never ship unreviewed AI code to production.

The Review Checklist

1. Logic Verification

□ Does it solve the actual problem?
□ Is the algorithm correct?
□ Are edge cases handled?
□ Is the control flow logical?
□ Do loops terminate properly?

Example: Checking Logic

AI generates:

function findMax(numbers: number[]): number {
  return Math.max(...numbers);
}

Review questions:

  • What if array is empty? (Returns -Infinity, might want null or throw)
  • What about very large arrays? (Stack overflow with spread)
  • Is null/undefined handled?

2. Type Safety

□ Are types properly defined?
□ Any use of 'any'?
□ Are generics used appropriately?
□ Null/undefined handling?
□ Type narrowing in conditionals?

Example: Spotting Type Issues

AI generates:

function getUserData(id: string): User {
  const data = localStorage.getItem(`user_${id}`);
  return JSON.parse(data);  // ⚠️ Problem!
}

Issues:

  • getItem can return null
  • JSON.parse(null) throws
  • No type validation on parsed data

Fixed:

function getUserData(id: string): User | null {
  const data = localStorage.getItem(`user_${id}`);
  if (!data) return null;
  try {
    return JSON.parse(data) as User;  // Consider runtime validation
  } catch {
    return null;
  }
}

3. Error Handling

□ Are errors caught appropriately?
□ Are error messages helpful?
□ Does error handling prevent crashes?
□ Are errors logged?
□ Are errors propagated correctly?

Example: Missing Error Handling

AI generates:

async function fetchUser(id: string) {
  const response = await fetch(`/api/users/${id}`);
  return response.json();  // ⚠️ Problems!
}

Issues:

  • No check for response.ok
  • No try/catch for network errors
  • No handling for non-JSON responses

4. Security Scan

□ Input validation present?
□ No SQL/NoSQL injection?
□ No XSS vulnerabilities?
□ Proper authentication checks?
□ No exposed secrets?
□ Safe data handling?

Example: Security Issue

AI generates:

app.get('/user/:id', (req, res) => {
  const query = `SELECT * FROM users WHERE id = ${req.params.id}`;
  db.execute(query);  // ⚠️ SQL Injection!
});

Fixed:

app.get('/user/:id', (req, res) => {
  const query = 'SELECT * FROM users WHERE id = ?';
  db.execute(query, [req.params.id]);
});

5. Performance Check

□ No unnecessary loops?
□ Database queries optimized?
□ Memory usage reasonable?
□ No blocking operations?
□ Caching considered?

Example: Performance Issue

AI generates:

async function getAllUserPosts(userIds: string[]) {
  const posts = [];
  for (const id of userIds) {
    const userPosts = await db.posts.findMany({ where: { userId: id } });
    posts.push(...userPosts);
  }
  return posts;
}

Issue: N+1 query problem

Fixed:

async function getAllUserPosts(userIds: string[]) {
  return db.posts.findMany({
    where: { userId: { in: userIds } }
  });
}

Common AI Code Patterns to Watch

Pattern 1: Over-Engineering

AI sometimes generates overly complex solutions:

// AI generated
class UserValidator {
  private static instance: UserValidator;
  private validationRules: Map<string, Rule[]>;

  private constructor() {
    this.validationRules = new Map();
    this.initializeRules();
  }

  static getInstance() {
    if (!this.instance) {
      this.instance = new UserValidator();
    }
    return this.instance;
  }
  // ... 100 more lines
}

// What was needed
function validateEmail(email: string): boolean {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

Pattern 2: Missing Null Checks

// AI generated
function getUsername(user: User): string {
  return user.profile.displayName.toUpperCase();
}

// What's needed
function getUsername(user: User): string {
  return user?.profile?.displayName?.toUpperCase() ?? 'Anonymous';
}

Pattern 3: Incorrect Async Handling

// AI generated
async function processItems(items: Item[]) {
  items.forEach(async (item) => {  // ⚠️ Won't await!
    await processItem(item);
  });
}

// Fixed
async function processItems(items: Item[]) {
  await Promise.all(items.map(item => processItem(item)));
}

Pattern 4: Incomplete Error Boundaries

// AI generated
try {
  const data = await fetch('/api/data');
} catch (error) {
  console.log('Error');  // ⚠️ Swallowed error, no context
}

// Fixed
try {
  const data = await fetch('/api/data');
} catch (error) {
  console.error('Failed to fetch data:', error);
  throw new ApiError('DATA_FETCH_FAILED', error);
}

Review Workflow

Step 1: Quick Scan

  • Read through once for overall understanding
  • Note anything that feels "off"

Step 2: Deep Analysis

  • Check each function's logic
  • Trace data flow
  • Verify error handling

Step 3: Security Audit

  • Look for injection points
  • Check authentication/authorization
  • Review data exposure

Step 4: Test Mentally

  • Imagine edge case inputs
  • Consider failure scenarios
  • Think about performance at scale

Step 5: Request Changes

Ask AI to fix:
"In the generated code, I noticed:
1. Missing null check on line 23
2. SQL injection vulnerability on line 45
3. N+1 query issue in getUserPosts

Please fix these issues."

Tools for Review

TypeScript Strict Mode

// tsconfig.json
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true
  }
}

ESLint Security Rules

// .eslintrc
{
  "plugins": ["security"],
  "extends": ["plugin:security/recommended"]
}

Manual Testing

For each function:
├── Test with valid input
├── Test with empty input
├── Test with null/undefined
├── Test with invalid types
└── Test with edge cases

Review Principle: The 30 seconds you spend reviewing can save hours of debugging in production. Make review a habit, not an afterthought.

In the next lesson, we'll cover common bugs in AI-generated code and how to fix them. :::

Quiz

Module 5: Debugging AI-Generated Code

Take Quiz