AI-written code is very good at green. The bugs below don't throw, don't log and don't fail a test. Every one of them was caught in a real code review of a large open-source app. We read 2,675 review threads to find them. Each comes with a yes/no question for your own app and a before/after you can copy (our own example code).
01 / 10The schema threw your new field away
Check: for the last field you added to an endpoint, is there a test that sends it and asserts it was stored?
Why: most validation libraries drop unknown keys by default. The request validates, the handler never sees the field.
// before: `limit` is missing from the schema, so parse() silently removes it
const Update = z.object({ name: z.string() });
// after: list the field, and make unknown keys an error
const Update = z.object({ name: z.string(), limit: z.number().int().optional() }).strict();02 / 10200 OK, nothing written
Check: does every update test read the record back and assert the new value?
Why: when public and internal names differ, a missing mapping passes undefined, and most ORMs read that as “don't change”.
// before: the API sends `expires_at`; this is undefined, so the column never changes
data: { title: input.title, expiresAt: input.expiresAt }
// after: map at the boundary, and test the write, not the status code
data: { title: input.title, expiresAt: input.expires_at }
expect((await getDoc(id)).expiresAt).toEqual(newDate);03 / 10The AI check didn't run, and said “fine”
Check: when an AI or fraud check is skipped (quota, timeout, rate limit), does the caller see “skipped”, not “pass”?
// before: out of quota looks exactly like "checked, nothing found", and gets cached
if (!(await hasQuota(workspace))) return { flagged: false };
// after: a third state the caller can't mistake for a pass
if (!(await hasQuota(workspace))) return { status: "skipped", reason: "quota" } as const;04 / 10Zero means “not set”
Check: do any of your API options treat 0 or "" as “not provided”?
// before: limit 0 → no limit at all
if (opts.limit) query = query.limit(opts.limit);
// after
if (opts.limit !== undefined) query = query.limit(opts.limit);05 / 10Nobody selected → everybody gets it
Check: can a filter that removes every recipient turn into “send to everyone”?
// before: every selected person left the project, so this falls back to all members
const to = selected.length ? selected : allMembers;
// after: an empty selection fails closed
if (selected.length === 0) throw new Error("Choose recipients again");06 / 10The test that can't fail
Check: does each “must never include” test first create the thing that must not appear?
// before: passes because no agent exists
it("never exports agents", async () => expect((await exportAll()).agents).toHaveLength(0));
// after: create one first, so the test proves the guard
it("never exports agents", async () => {
await createAgent();
expect((await exportAll()).agents).toHaveLength(0);
});07 / 10“Not found” while it's still loading
Check: does any screen show “not found”, redirect or close a panel before the request has finished?
Why: a mock answers instantly, so this never shows up until the real API is plugged in.
// before
const { data } = useQuery(detailsQuery(id));
if (!data) return <NotFound />;
// after
const { data, isPending } = useQuery(detailsQuery(id));
if (isPending) return <Spinner />;
if (!data) return <NotFound />;08 / 10The dry run that wasn't dry
Check: does your “validate / preview / dry run” mode skip every side effect, and catch unique-field conflicts?
// before: validation runs the same hooks as a real save, including the one that calls the payment provider
await runHooks("beforeChange", doc);
return { valid: true };
// after: hooks know it's a dry run, and uniqueness is checked, not assumed
await runHooks("beforeChange", doc, { dryRun: true });
await assertUniqueFields(doc);
return { valid: true };09 / 10Bulk action, single result
Check: pick two rows and run each bulk action. Does every one act on both, or refuse?
// before: two rows selected, one activated, no error
await activate(selectedIds[0]);
// after: act on all of them, or hide the action for multi-select
await Promise.all(selectedIds.map(activate));10 / 10Validating the placeholder
Check: where your app fills templates (emails, prompts, workflow actions), does validation run on the filled-in value?
// before: the URL check sees "{{url}}" and strips it
return fill(sanitizeUrl(template.href), vars);
// after: fill first, then check what will actually be sent
return sanitizeUrl(fill(template.href, vars));Run itFind these in your own app in an afternoon
- List the last 5 fields you added. For each, write one test that sends it and reads it back.
- Search for
if (on numeric options, and|| all,?? all,: allfallbacks on lists. - Find every
return { ok: true }/flagged: falseon an early-exit path. - Search tests for
toHaveLength(0),toBeNull()andnot.toContain, and check each one creates something first. - Switch your dev API mock to a 2-second delay for a day.
P.S. If you want a senior engineer to read your AI-built codebase for the bugs that don't throw: invental.co/experts