Taxonomy
Twenty-five ways code is wrong.
One lesson per class: what it looks like, why it survives review, and the reading habit that catches it. The vocabulary is deliberately language-neutral — these are the categories a reviewer thinks in, not TypeScript features.
Boundaries
Where does the range actually stop?
- Off-by-oneA bound is one out, so the first or last element is included or skipped wrongly3 exercises
- Empty and single-element collectionsCode that is correct for many items breaks on none or exactly one1 exercise
- Silent truncationA value is quietly cut to fit rather than rejected for not fitting2 exercises
- Pagination boundaryA page boundary drops or repeats a row, or the last page never terminateslesson only
Conditions
Is this test asking the question it looks like it is asking?
- Missing null or undefined guardA value that can legitimately be absent is used as though it never is1 exercise
- Wrong comparison operatorStrict where it should be loose, or the inequality points the wrong way10 exercises
- Wrong logical connectorAn and where an or belongs, or a negation that did not distribute5 exercises
- Incorrect early returnA guard clause returns before work that still needed doinglesson only
Failure handling
What happens when this goes wrong?
Time and concurrency
What else can happen between these two lines?
- Unawaited promiseAsynchronous work is started and never waited for, so its result and its failure both escapelesson only
- Check-then-act across an awaitA condition is verified, the function suspends, and it acts on what was true beforelesson only
- Resource never releasedA handle, lock or timer is acquired on a path that never gives it back1 exercise
State and ownership
Who owns this value, and who is allowed to change it?
- Mutation of a caller's inputAn argument is modified in place, changing a value the caller still holds2 exercises
- Shared mutable defaultA default value is created once and shared across every call that omits itlesson only
- Cache key missing a dimensionTwo requests that should differ share a key, so one is served the other's answer1 exercise
Trust
What is this trusting that it has not checked?
- Missing authorisation checkThe request is authenticated but never checked against what this user may do1 exercise
- Unvalidated input reaching a sinkCaller-controlled data arrives somewhere that interprets it without being checked2 exercises
- Catastrophic backtrackingA regular expression whose cost explodes on an input that never matcheslesson only
- Leaky error messageA failure reports internal detail the caller was not meant to learn1 exercise
Data and representation
Is this the same value it was a moment ago?
- Integer and float precision on moneyCurrency is held or rounded in a way that loses or invents fractions of a unit2 exercises
- Timezone and DSTA date is treated as absolute when it is local, or a day is assumed to be 24 hours1 exercise
- Locale-dependent comparisonCase folding, sorting or number parsing that changes answer with the machine's locale2 exercises
Dependencies
Does this API do what its name says?