review agent failed to quote the right code line: off-by-one in diff position: how to fix
Fixes a review agent quoting the wrong code line by correcting 0-based vs 1-based indexing in its diff position math, and covering it with fixture tests. Use when inline comments quote a line adjacent to the intended one. Triggers: consistent one-line shifts in quoted code. Not for completely misplaced comments, or stale hunks after force-push.
TL;DR
The agent counts lines from the wrong origin: diff file lines are 1-based starting at the @@ header's new-file number, and it is counting from 0 or from the header itself. Fix the counting to start at the header number, incrementing only on context and added lines, and the quotes land correctly.
The error
review agent failed to quote the right code line: off-by-one in diff position: how to fix
(comment quotes `db.connect()` but the finding is about the `db.query()` call on the next line)Steps
1. Read the hunk header correctly
For @@ -10,5 +12,7 @@, new-file lines start at 12, and line numbers are 1-based. Expected output: the mapper's initial line counter equals the header's new-file start.
2. Walk the hunk lines with the right increments
Context and added lines advance the new-file counter; removed lines do not (they have no new-file number). Expected output: every added or context line maps to its true file line.
3. Verify by quoting and checking
For each comment, fetch the mapped line from the file and confirm it matches the code the finding describes. Expected output: quoted lines match the findings they annotate.
4. Add fixture tests with a known diff
Write a test with a hand-computed diff and assert each mapped line. Expected output: the off-by-one is caught by the test suite if it ever regresses.
When to use
- Inline comments consistently quote the line above or below the intended one
- Every quoted snippet is shifted by exactly one
- The shift reproduces on fresh diffs, not just stale ones
When not to use
- Comments landing on completely unrelated lines (a mapping bug, not an off-by-one)
- Stale hunks after a force-push (re-fetch the diff instead)
- The API rejecting positions outright
Tool compatibility
- Unified diff format from git and the GitHub compare API
- The 1-based convention is the same on GitLab
- Any agent-side position mapper, LLM or deterministic
Variant phrasings
quoted line shifted after a rebase
The diff changed under the agent. Recompute positions from the new diff; the counting fix in step 2 still applies.
context lines miscounted in the quote
The mapper probably increments on removed lines too. Removed lines belong to the old file only.
comment quotes the hunk header line itself
The counter started at the header instead of the header's line number. Step 1 fixes this variant directly.
Why it happens
There are three plausible origins to count from: 0, the header line, or the header's stated line number. Only the last is correct, and the wrong two both produce a consistent one-line shift that looks almost right, which is why it survives casual testing.
Edge cases
- Deleted lines have no new-file line number at all: never anchor a comment to one.
- Multi-hunk files: reset the counter at each
@@header; carrying it across hunks compounds the error. - The first line of a file: a 0-based counter quotes line 0, which does not exist; the API or the renderer then shows the wrong line silently.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_jlQ8sWNd-CPjS8ZRjZlixw