micro-editor/micro · info
no next diff hunk
Error message
no next diff hunk
What it means
Returned by (*Buffer).FindNextDiffLine (internal/buffer/buffer.go:1447) when the scan walks past the end of the buffer (curLine < 0 or > LinesNum()) without the diff status changing to a new hunk. In other words: from startLine in the given direction there is no further changed/unchanged boundary — you're already at the last (or first) diff hunk. It is a search-exhausted sentinel, not a fault.
Source
Thrown at internal/buffer/buffer.go:1447
// FindNextDiffLine returns the line number of the next block of diffs.
// If `startLine` is already in a block of diffs, lines in that block are skipped.
func (b *Buffer) FindNextDiffLine(startLine int, forward bool) (int, error) {
if b.diff == nil {
return 0, errors.New("no diff data")
}
startStatus, ok := b.diff[startLine]
if !ok {
startStatus = DSUnchanged
}
curLine := startLine
for {
curStatus, ok := b.diff[curLine]
if !ok {
curStatus = DSUnchanged
}
if curLine < 0 || curLine > b.LinesNum() {
return 0, errors.New("no next diff hunk")
}
if curStatus != startStatus {
if startStatus != DSUnchanged && curStatus == DSUnchanged {
// Skip over the block of unchanged text
startStatus = DSUnchanged
} else {
return curLine, nil
}
}
if forward {
curLine++
} else {
curLine--
}
}
}
// SearchMatch returns true if the given location is within a match of the last search.View on GitHub (pinned to 1c8b82b32e)
Solutions
- Treat it as 'no more hunks': reverse direction (use PrevDiff) or jump back with > goto / undoline
- Re-run > diff to refresh hunk positions if you believe changes exist beyond the cursor (stale diff state after edits)
- In plugins, break the loop on this error rather than retrying
Example fix
// before
for {
l, err := h.Buf.FindNextDiffLine(cur, true)
cur = l // ignores err, loops forever at EOF
}
// after
for {
l, err := h.Buf.FindNextDiffLine(cur, true)
if err != nil { break } // no next diff hunk -> done
cur = l
} Defensive patterns
Strategy: try-catch
Validate before calling
// Bound the search yourself so exhaustion is expected, not exceptional
to := h.Buf.LinesNum()
if forward && cur >= to-1 { /* nothing ahead: skip the call */ }
if !forward && cur <= 0 { /* nothing behind: skip the call */ }
dl, err := h.Buf.FindNextDiffLine(cur, forward) Try / catch
for {
l, err := h.Buf.FindNextDiffLine(cur, true)
if err != nil {
if err.Error() == "no next diff hunk" {
break // sentinel: reached last hunk in this direction — stop cleanly
}
return err // unexpected
}
cur = l
} Prevention
- Treat 'no next diff hunk' as loop termination, never as an error to log loudly
- Refresh with > diff after edits; hunks shift as you type
- Alternate Next/Prev to walk back instead of probing past EOF repeatedly
When it happens
Trigger: Cursor sits in/below the final changed hunk and NextDiff is invoked (forward scan hits EOF); or cursor is above the first hunk and PrevDiff is invoked (backward scan hits BOF). Emitted by the NextDiff/PrevDiff actions in internal/action/actions.go.
Common situations: Repeatedly pressing the next-diff binding to review changes and running one press past the last hunk; macros that loop diffs without an exit condition.
Related errors
AI-assisted analysis of micro-editor/micro@1c8b82b32e (2026-08-15).
Data as JSON: /api/errors/2e8bb1f344963792.
Report an issue: GitHub.