SoftwareSideHustles
Skills

Common Mistakes When Reviewing AI-Generated Code

Ten mistakes reviewers make with AI-written code — from trusting the explanation to ignoring untested requirements — and how to avoid each one.

By Software Side Hustles Editorial Team · Published · Updated · 5 min read

AI-generated code fails in characteristic ways, and reviewers miss it in characteristic ways too. These are the mistakes we see most often.

1. Trusting the explanation instead of the code

Models describe what code should do, and the description is often more correct than the code. Read the code as if the explanation didn't exist, then compare.

Example: a response says its deduplication function "preserves the order of first appearance", but ends with .sort((a, b) => a - b). The description and the code disagree, and the code wins.

2. Treating passing tests as proof

Tests only check what they check. In the deduplication example, inputs such as [1, 1, 2, 3, 3] produce the expected output because they are already sorted, hiding the bug. Ask: which inputs would distinguish a correct solution from this one? Then trace those.

3. Ignoring requirements no test covers

Documentation, output format, naming, "don't modify the input", "one line only" — these rarely have tests. Make a checklist of every explicit instruction and tick each one off. A response can pass every test and still be only partially correct.

4. Forgetting the boring edge cases

The same handful of inputs catch a large share of bugs:

  • empty input ([], "", None);
  • exactly one element;
  • duplicates;
  • negative numbers and zero;
  • maximum sizes from the constraints;
  • inputs that don't divide evenly (chunking, pagination).

Example: range(0, len(items) - size + 1, size) looks like careful bounds checking, but it silently drops the final partial chunk — and for chunk([1, 2], 5) it returns an empty list.

5. Missing language-specific traps

Models reproduce plausible-looking code that trips over well-known language behaviours:

javascript
[10, 9, 1].sort(); // [1, 10, 9] — default sort compares strings
[10, 9, 1].sort((a, b) => a - b); // [1, 9, 10]
python
def add(item, bucket=[]): # default list is created once and shared
bucket.append(item)
return bucket
add(1)
add(2) # returns [1, 2], not [2]
python
0.1 + 0.2 == 0.3 # False: 0.1 + 0.2 is 0.30000000000000004

Keep a personal list of these for the languages you review.

6. Accepting confident claims about libraries

"This library supports X natively" is exactly the kind of claim models get wrong. If supporting documentation is provided, check the claim against it. If it isn't, say the claim is unverified rather than assuming it is true or false.

7. Over-criticising correct code

The opposite failure: inventing problems to look rigorous. If code is correct and adequate for the constraints, say so. Suggesting a "faster" algorithm when the input has twenty elements, or demanding a different style, adds noise and can make your overall rating less accurate.

8. Confusing style with correctness

"I would have used a comprehension" is a preference. "This mutates the caller's list despite the instruction not to" is a defect. Keep them in separate parts of your review, and weight them very differently.

9. Ignoring side effects and security

Look for:

  • mutation of inputs or global state;
  • user input reaching a shell, SQL query or file path unvalidated;
  • secrets printed, logged or hard-coded;
  • broad except: / catch blocks that swallow errors;
  • resources (files, connections) not closed.

10. Writing vague verdicts

"Doesn't work" is not actionable. Name the failing input, the actual and expected output, the violated requirement and the minimal fix:

chunk([1, 2, 3, 4, 5], 2) returns [[1, 2], [3, 4]]; expected [[1, 2], [3, 4], [5]]. The range end len(items) - size + 1 excludes the final partial chunk. Use range(0, len(items), size).

11. Judging performance only on the happy path

A solution that is fast on the example input can be slow on the inputs that matter. When the brief states sizes, do the arithmetic:

  • a nested loop over 100,000 items performs about 5 × 10⁹ comparisons in the worst case;
  • a linear scan repeated for every lookup turns an O(n) step into O(n × queries);
  • building a string by repeated concatenation in a loop can be quadratic, while collecting parts and joining them once is linear.

Also check which case you are reasoning about. An early return makes the best case fast but leaves the worst case unchanged, and the worst case is usually the one the constraints describe.

12. Reviewing in the wrong order

Starting with naming, formatting or idioms anchors your judgement on the least important issues. A reliable order is:

  1. Does it meet every explicit requirement?
  2. Is it correct for every allowed input?
  3. Is it fast and memory-efficient enough for the stated constraints?
  4. Is it safe (inputs, secrets, side effects)?
  5. Is it clear and idiomatic?

Stopping at the first serious defect is fine for a verdict, but list everything material you found so the feedback is complete.

Build your own trap list

Every reviewer develops a personal list of patterns that have fooled them before. Start one now and add to it whenever you miss something in practice:

PatternWhat to check
SortingDefault comparator, stability, whether the input is mutated
Slicing and rangesInclusive or exclusive ends, the last partial chunk, empty ranges
DefaultsMutable default arguments, None versus empty collections
NumbersInteger overflow, float equality, rounding mode (Python's round(2.5) is 2)
StringsEncoding, case, whitespace, user-perceived characters versus code points
ErrorsSwallowed exceptions, wrong exception types, missing validation

Reviewing against a list feels slower at first but quickly becomes automatic.

A quick pre-submit checklist

  • I listed every explicit requirement and checked each.
  • I traced at least one input that would expose each likely bug.
  • I checked the explanation's claims against the code.
  • I separated defects from style preferences.
  • My verdict cites specific inputs or lines.

Practise

Every exercise in our Response Evaluation lab contains at least one of these mistakes waiting to be caught — and one where every test passes but a requirement is still missed.

About the author

Written and reviewed by the Software Side Hustles editorial team. Code examples are executed before publication, and platform facts link to the platform's own pages with the date they were checked.

Our editorial policy

Cookies on this site

We use essential cookies to run the questionnaire, practice labs and sign-in. With your permission we'd also like to use analytics to understand which pages help people. Rejecting never limits any feature. Cookie policy