Fix AI generated code by starting with what you can see: broken endpoints, silent failures, or security warnings. I’ve been bitten by this more times than I can count - AI tools spit out code that looks right but fails in production. Here’s how to find and fix the real issues.
What are the most common vulnerabilities in AI generated code?
The most common vulnerabilities I see are hardcoded secrets, SQL injection via string concatenation, and missing input validation. AI often pulls patterns from public repos without understanding context. For example, it might generate a login endpoint like this:
@app.post("/login")
def login(username: str, password: str):
query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
return db.execute(query).fetchone()
This is an SQL injection waiting to happen. Never trust user input in a query string. Fix it by using parameterized queries with SQLAlchemy:
@app.post("/login")
def login(username: str, password: str):
stmt = text("SELECT * FROM users WHERE username=:username AND password=:password")
return db.execute(stmt, {"username": username, "password": password}).fetchone()
Another frequent issue is leaving debug modes on or exposing internal errors. AI doesn’t know your deployment setup. Always override defaults in production:
# In your FastAPI app setup
app = FastAPI(debug=False) # Never True in prod
How do I detect logic errors in AI generated Python?
Detect logic errors by writing tests that mirror real user flows, not just unit tests on functions. AI often gets the “what” right but misses the “when” and “why.” For example, it might generate a user creation endpoint that doesn’t handle duplicate emails:
@app.post("/users")
def create_user(user: UserCreate):
db_user = UserModel(**user.dict())
db.add(db_user)
db.commit()
return db_user
This will crash on duplicate email if your DB has a unique constraint. Instead, catch the integrity error:
from sqlalchemy.exc import IntegrityError
@app.post("/users")
def create_user(user: UserCreate):
db_user = UserModel(**user.dict())
db.add(db_user)
try:
db.commit()
except IntegrityError:
db.rollback()
raise HTTPException(status_code=400, detail="Email already registered")
return db_user
Write a test that tries to create two users with the same email. If it passes, your logic holds. I use Pytest with fixtures to isolate DB state:
def test_duplicate_email_rejected(client, db_session):
client.post("/users", json={"email": "a@b.com", "password": "x"})
response = client.post("/users", json={"email": "a@b.com", "password": "y"})
assert response.status_code == 400
assert "Email already registered" in response.json()["detail"]
How do I fix security flaws in FastAPI endpoints from AI output?
Fix security flaws by assuming every AI-generated endpoint is insecure until proven otherwise. Start with authentication, then input validation, then rate limiting. AI often skips auth entirely or uses fake tokens.
Here’s a typical AI-generated endpoint missing auth:
@app.get("/data")
def get_data():
return {"sensitive": "info"}
Add real auth using FastAPI’s dependencies. I use JWT with a simple verification function:
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
security = HTTPBearer()
def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
token = credentials.credentials
# In real life: verify signature, expiry, etc.
if token != "valid-token-for-demo":
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid token",
)
return token
@app.get("/data")
def get_data(token: str = Depends(verify_token)):
return {"sensitive": "info"}
Then validate inputs with Pydantic. Never accept raw dicts. AI often does this:
@app.post("/update")
def update_item(data: dict): # Bad
return {"received": data}
Fix it with a model:
from pydantic import BaseModel
class UpdateItem(BaseModel):
item_id: int
value: str
@app.post("/update")
def update_item(item: UpdateItem):
return {"updated": item.item_id}
This catches malformed JSON early and documents your API.
How do I validate AI-generated SQLAlchemy models?
Validate SQLAlchemy models by checking constraints, relationships, and migrations. AI often creates models without nullable defaults, wrong cascade rules, or missing indexes. I once saw a model where created_at had no default and wasn’t indexed - causing slow queries and NULL errors.
Here’s a risky AI-generated model:
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
email = Column(String) # No unique, no index
password = Column(String)
Fix it by adding constraints and indexes that match your business rules:
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
email = Column(String, unique=True, index=True, nullable=False)
password = Column(String, nullable=False)
created_at = Column(DateTime, server_default=func.now(), nullable=False)
Use Alembic to generate migrations after you fix the model. Then run them in a staging DB before deploying. Never skip this step - AI doesn’t know your schema evolution.
How do I test AI-generated API contracts with Pytest?
Test API contracts by treating your OpenAPI spec as the source of truth. AI often generates endpoints that don’t match the declared schema - missing fields, wrong types, or extra keys. I use Pytest to validate responses against the schema.
First, generate your OpenAPI JSON:
curl http://localhost:8000/openapi.json > openapi.json
Then write a test that checks every endpoint:
import jsonschema
import json
with open("openapi.json") as f:
OPENAPI_SCHEMA = json.load(f)
def test_api_matches_schema(client):
for path, path_item in OPENAPI_SCHEMA["paths"].items():
for method, operation in path_item.items():
if method.lower() in ["get", "post", "put", "delete", "patch"]:
response = client.request(method, path)
jsonschema.validate(
instance=response.json(),
schema=operation["responses"]["200"]["content"]["application/json"]["schema"]
)
This catches mismatches early. If AI adds a field not in the schema, the test fails. If it omits a required one, same thing. It’s saved me from silent data corruption more than once.
How do I refactor AI-generated async code for production?
Refactor AI-generated async code by removing blocking calls and ensuring proper error propagation. AI often mixes sync and async or forgets to await. I’ve seen endpoints that call time.sleep(5) inside an async function - destroying concurrency.
Here’s a bad example:
@app.get("/slow")
async def slow_endpoint():
time.sleep(2) # Blocking!
return {"done": True}
Fix it by using asyncio.sleep if you need a delay, or better - remove the delay entirely. For real work like HTTP calls, use httpx.AsyncClient:
import httpx
@app.get("/fetch")
async def fetch_external():
async with httpx.AsyncClient() as client:
resp = await client.get("https://api.example.com/data")
return resp.json()
Also, watch for missing try/except blocks. AI often omits error handling in async code. Wrap external calls:
@app.get("/fetch")
async def fetch_external():
try:
async with httpx.AsyncClient() as client:
resp = await client.get("https://api.example.com/data")
resp.raise_for_status()
return resp.json()
except httpx.RequestError as e:
raise HTTPException(status_code=502, detail=f"External error: {str(e)}")
Finally, use logging instead of print. AI loves print - it’s useless in production. Use structlog or Python’s logging module with JSON output.
When NOT to trust AI generated code
Don’t trust AI generated code for authentication, payment processing, or any code handling PII. I’ve seen AI generate OAuth flows that skipped state validation - critical for security. For those, use battle-tested libraries like fastapi-users or python-jose and read the docs.
Also, avoid using AI to generate migration scripts. Schema changes are too risky. Write them yourself or use Alembic’s autogenerate with careful review.
AI is great for boilerplate, repetitive CRUD, or getting unstuck on a tricky algorithm. But production systems need human judgment. Treat AI output like a junior engineer’s first draft: review it, test it, and break it on purpose.
If you’re stuck fixing AI generated code in your FastAPI or data stack, I’ve helped indie builders do this exact work. You can hire me to audit your endpoints, write tests, and make your AI-generated code production ready - no fluff, just fixes.
FAQ
How do I know if my AI generated code has SQL injection?
Look for string concatenation with user input in SQL queries. If you see f"SELECT ... {user_input}" or + user_input +, it’s vulnerable. Fix it with parameterized queries or ORM methods.
Can I use AI to generate my FastAPI auth system?
Not safely. AI often misses token validation, scope checks, or refresh token handling. Use a trusted library and have AI only generate non-critical parts like route stubs or response models.
What’s the fastest way to validate AI generated Python?
Run it through a linter like ruff or flake8, then write a test that exercises the happy path and one edge case. If it passes both, it’s likely safe for low-risk code.
Should I use AI to generate database migrations?
No. Migrations alter your data schema. A mistake can corrupt or lose data. Write them manually, test them in a copy of production, and review every line.
Key Takeaways
- Fix AI generated code by assuming it’s insecure and untested until proven otherwise
- Use parameterized queries, Pydantic models, and explicit error handling
- Test API contracts against your OpenAPI schema to catch mismatches early
- Never use AI for auth, payments, or migrations - human review is non-negotiable
- Treat AI output as a draft: review, test, and break it before deploying to prod
Top comments (0)