Programming with AI
ENRU
2.14

Red flags in generated code

ten signs worth a closer look

What it is

The closing article of the chapter: a list of what turns up most often in AI-written code and most often turns out to be a problem. A red flag is not a verdict, it is a reason to stop and read more carefully.

All ten rest on the earlier articles, so they read quickly — this is a summary, not new material.

What to look for

1. Swallowed errors

try:
    data = fetch_weather(city)
except Exception:
    pass

The program doesn't crash and therefore looks like it works. In reality wrong data travels on, and the cause surfaces nowhere. The same family: except: return None and .get(key, {}) where the field is required (articles 2.8, 2.13).

2. Defaults instead of errors

temp = data.get("main", {}).get("temp", 0)

Zero degrees looks like a real answer. If a field is required, its absence is an error, not an excuse to substitute a number.

3. Invented libraries and methods

An import of a package that doesn't exist, or a call to a method the library doesn't have. The code looks confident and fails on the first run. Cured by checking the version (article 2.11) and a quick look at the documentation.

4. A blocking call in asynchronous code

async def handler(message):
    r = requests.get(url)       # stops everything

The bot stops answering everyone for the duration of one request (article 2.10).

5. Secrets in the code

TOKEN = "7123456789:AAE-abcdef..."

It goes into git and stays in the history forever. Tokens come from environment variables, nowhere else.

6. Code outside functions

The line conn = sqlite3.connect(DB_PATH) at the top level of a file runs on import — not when you expect, and not only once (article 2.2).

7. A mutable default value

def add_item(item, cart=[]):

The list is created once and stays shared across every call (article 2.5).

8. The function does more than was asked

Logging, caching, retries and validation have appeared inside, none of which was discussed. Not necessarily harmful, but it is code you did not order and did not check.

9. Quietly modifying what was passed in

def add_tax(items: list[dict], rate: float) -> None:
    for item in items:
        item["price"] = ...

Outside the function the data changed too. A second call charges tax on the tax (article 2.5).

10. Comments instead of code

# Access rights need to be checked here
# TODO: handle the empty list case
return result

The comment describes something the code does not do. It looks like a considered decision and is in fact a hole, politely labelled.

What to tell the AI

One prompt to check with, after the code arrives and before you accept it:

Prompt
Check your own code against this list:
- swallowed exceptions and defaults instead of errors
- calls to methods that may not exist in this library version
- blocking calls inside async
- secrets in the code
- code outside functions
- mutable default values in arguments
- modifying data passed in as an argument

Which of these are present? If none, say so.

A prompt like this works better than a general "review this": it names what to look for (article 3.8).

Cheat sheet

  • Swallowed errors: except Exception: pass, .get() instead of a check.

  • A default instead of an error is an answer that lies.

  • Invented libraries and methods — check the version and the docs.

  • requests and time.sleep inside an async def.

  • Tokens in the code go into git history forever.

  • Code outside functions runs on import.

  • =[] in arguments, modifying what was passed, doing extra work.

  • # TODO in the code is a hole, not a solution.