DEV Community

tommy
tommy

Posted on

7 mistakes AI coding agents make in Next.js + Supabase apps (and the rules that stop them)

AI agents like Cursor and Claude Code write working code fast. They also ship the same handful of dangerous mistakes over and over, because "it runs" is not the same as "it's safe." Here are the seven I see most in Next.js + Supabase projects, plus the one-line rule you can drop into your agent's instructions to prevent each.

1. Using the service role key in client code

The agent hits a permissions error, grabs the service_role key, and the error goes away. So does your Row Level Security.
Rule: "Never import or reference the Supabase service role key outside server-only files. If a query fails on RLS, fix the policy, not the key."

2. Tables with RLS turned off

New tables get created, queries work in dev, and nobody enables RLS.
Rule: "Every new table must enable RLS and ship with explicit select/insert/update/delete policies in the same migration."

3. Trusting the client for auth checks

Hiding a button is not authorization.
Rule: "Check the session and ownership on the server in every Route Handler and Server Action that reads or writes user data."

4. Webhooks without signature checks or idempotency

Stripe-style webhooks get processed unverified, and retries grant access twice.
Rule: "Verify the webhook signature before parsing, and make handlers idempotent using the event ID."

5. Secrets leaking via NEXT_PUBLIC_

Anything prefixed NEXT_PUBLIC_ is shipped to the browser.
Rule: "Only public, non-secret values may use the NEXT_PUBLIC_ prefix."

6. Migrations that lock big tables

Adding an index or a NOT NULL column on a large table can lock it in production.
Rule: "Create indexes CONCURRENTLY, add columns nullable first, backfill, then add constraints. Include a rollback step."

7. N+1 queries hidden in loops

The agent fetches related rows one at a time inside a .map().
Rule: "Never query inside a loop. Batch with in() filters or joins, and paginate every list query."

How to actually make the agent follow these

Put them where the agent reads them every session:

  • Claude Code: CLAUDE.md in the repo root
  • Cursor: .cursor/rules/*.mdc
  • Codex and others: AGENTS.md

Keep each rule short and specific. Vague rules like "write secure code" get ignored; concrete ones like "never use the service role key in client code" stick.

For reviews, a second pass by a narrowly scoped "reviewer" agent (security, payments, migrations) catches far more than asking the same agent that wrote the code.


Disclosure: I sell two packs built around this approach. ShipSafe Rules is ready-made CLAUDE.md, AGENTS.md and Cursor rules for Next.js + Supabase. The Senior Engineer Agent Pack is five reviewer subagents for security, payments, migrations, performance and tests. Everything above works without them. Copy the rules and use them.

Top comments (0)