jesseduffield/lazygit · error
index outside of range of commits
Error message
index outside of range of commits
What it means
MovePatchIntoCommit (patch.go) validates that sourceCommitIdx is within the loaded commits slice before building todo changes; len(commits)-1 < sourceCommitIdx means the caller's index refers to a commit the model no longer contains. This is an internal consistency check between the UI's commit list and the command layer.
Source
Thrown at pkg/commands/git_commands/patch.go:147
return err
}
// amend the destination commit
if err := self.commit.AmendHead(); err != nil {
return err
}
self.rebase.onSuccessfulContinue = func() error {
self.PatchBuilder.Reset()
return nil
}
// continue
return self.rebase.ContinueRebase()
}
if len(commits)-1 < sourceCommitIdx {
return errors.New("index outside of range of commits")
}
// we can make this GPG thing possible it just means we need to do this in two parts:
// one where we handle the possibility of a credential request, and the other
// where we continue the rebase
if self.config.NeedsGpgSubprocessForCommit() {
return errors.New(self.Tr.DisabledForGPG)
}
baseIndex := sourceCommitIdx + 1
changes := []daemon.ChangeTodoAction{
{Hash: commits[sourceCommitIdx].Hash(), NewAction: todo.Edit},
{Hash: commits[destinationCommitIdx].Hash(), NewAction: todo.Edit},
}
self.os.LogCommand(logTodoChanges(changes), false)
err := self.rebase.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{View on GitHub (pinned to c477a2959b)
Solutions
- Re-check the index against the fresh model length at the call site before invoking (as the controllers do)
- Trigger a refresh of the commits view and retry the action after the model updates
- If reproducing programmatically, pass an index < len(commits) obtained from the same model snapshot
Example fix
// before
err := gitCommands.Patch.MovePatchIntoCommit(commits, selectedIdx, ...)
// after
if selectedIdx >= len(commits) {
return errors.New("selection out of range; refresh and retry")
}
err := gitCommands.Patch.MovePatchIntoCommit(commits, selectedIdx, ...) Defensive patterns
Strategy: validation
Validate before calling
if sourceCommitIdx < 0 || sourceCommitIdx >= len(commits) {
return fmt.Errorf("source index %d out of range for %d commits", sourceCommitIdx, len(commits))
}
return gitCommands.Patch.MovePatchIntoCommit(commits, sourceCommitIdx, destIdx) Try / catch
On 'index outside of range of commits', refresh the commit log and recompute indexes once; if it persists, abort — it signals model/view divergence, not a transient git failure.
Prevention
- Always compute indexes from the same []*models.Commit passed to the call
- Refresh the commits view after any rebase/branch-switch before allowing selection-based actions
- In tests, build the commits slice and indexes together
When it happens
Trigger: The commits reloaded between selection and action (background refresh, rebase finished, branch switched) so the selected index is now out of range; calling the API with a stale index in scripts/tests.
Common situations: Race between a worker refresh and the user pressing the move-patch keybinding; very short commit lists (index 0 selected, list becomes empty).
Related errors
- index outside of range of commits
- Todo %s not found in git-rebase-todo
- Feature not available for users using GPG. If you are using
- You are midway through another rebase operation. Please abor
- Feature not available for users using GPG. If you are using
AI-assisted analysis of jesseduffield/lazygit@c477a2959b (2026-08-15).
Data as JSON: /api/errors/d79b1a3ad131940c.
Report an issue: GitHub.