How to spot off-by-one errors in code review
An off-by-one error is a boundary that is one step wrong: the last item is never processed, a value exactly on the threshold falls on the wrong side. The code works for every input except the one at the edge, which is why tests that use round numbers miss it.
What it looks like in a diff
A loop bound or a division that stops one short: range(len(items) - 1), i < n - 1, a count divided without rounding up, a slice whose end excludes the item it should include.
A comparison at a stated threshold: the requirement says "18 or over" and the code says > 18, or a range is supposed to include its last day and the code compares against the start of that day. Read the requirement's wording ("up to", "at least", "through") and check the operator against it.
Questions to ask in review
- What is the first and the last value this loop or range handles, and should it handle them?
- Does the requirement state a boundary in words, and does the operator match those words?
- What happens when the total is not a round multiple of the batch or page size?
- Do the tests use a value exactly on the boundary?
How to word the comment
Name the input, the path it takes and what goes wrong, then the fix. For example (on an imagined PR, not one from the library):
The loop runs over days 0 to 5, so Sunday's numbers never make it into the weekly report. Loop over all seven days (
range(7)), and add a test with data on the last day.
Practise on real PRs
As of October 2026, the DiffDojo library has 15 live PRs that plant off-by-one errors, across 7 stacks. They are not listed here: a PR you open knowing its bug teaches less. Each review is graded on whether you find the bug and explain it.