{"record":{"id":"f682bbab88cbe0ff","repo":"jesseduffield/lazygit","slug":"index-outside-of-range-of-commits-f682bb","errorCode":null,"errorMessage":"index outside of range of commits","messagePattern":"index outside of range of commits","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/git_commands/rebase.go","lineNumber":427,"sourceCode":"\t\tif self.config.NeedsGpgSubprocessForCommit() {\n\t\t\treturn errors.New(self.Tr.DisabledForGPG)\n\t\t}\n\n\t\treturn self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{\n\t\t\tbaseHashOrRoot:             getBaseHashOrRoot(commits, commitIndex),\n\t\t\tinstruction:                daemon.NewInsertBreakInstruction(),\n\t\t\tkeepCommitsThatBecomeEmpty: keepCommitsThatBecomeEmpty,\n\t\t}).Run()\n\t}\n\n\treturn self.BeginInteractiveRebaseForCommitRange(commits, commitIndex, commitIndex, keepCommitsThatBecomeEmpty)\n}\n\nfunc (self *RebaseCommands) BeginInteractiveRebaseForCommitRange(\n\tcommits []*models.Commit, start, end int, keepCommitsThatBecomeEmpty bool,\n) error {\n\tif len(commits)-1 < end {\n\t\treturn errors.New(\"index outside of range of commits\")\n\t}\n\n\t// we can make this GPG thing possible it just means we need to do this in two parts:\n\t// one where we handle the possibility of a credential request, and the other\n\t// where we continue the rebase\n\tif self.config.NeedsGpgSubprocessForCommit() {\n\t\treturn errors.New(self.Tr.DisabledForGPG)\n\t}\n\n\tchanges := make([]daemon.ChangeTodoAction, 0, end-start)\n\tfor commitIndex := end; commitIndex >= start; commitIndex-- {\n\t\tchanges = append(changes, daemon.ChangeTodoAction{\n\t\t\tHash:      commits[commitIndex].Hash(),\n\t\t\tNewAction: todo.Edit,\n\t\t})\n\t}\n\tself.os.LogCommand(logTodoChanges(changes), false)\n","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/jesseduffield/lazygit/blob/c477a2959b229fbf3284be0d4d2904ab61ec3c94/pkg/commands/git_commands/rebase.go#L409-L445","documentation":"BeginInteractiveRebaseForCommitRange validates that the `end` index fits the commits slice (len(commits)-1 < end) before building ChangeTodoActions for indexes start..end. An out-of-range end would panic on commits[commitIndex].Hash(), so this is a fail-fast guard against a stale or inconsistent commit list.","triggerScenarios":"Calling the range rebase with an end index computed from an older model snapshot; controllers passing selection indexes after the log shrank (branch switched, commits squashed away); direct API use in tests.","commonSituations":"Racing a background refresh; selecting a deep commit then the history changing; programmatic callers reusing cached indexes.","solutions":["Validate `end < len(commits)` (and start <= end) at the call site with a freshly refreshed commits slice","Trigger a commits refresh and recompute the selection before invoking","In scripts, derive indexes from the same []*models.Commit you pass in"],"exampleFix":"// before\nerr := rebaseCmd.BeginInteractiveRebaseForCommitRange(commits, start, end, false)\n\n// after\nif end >= len(commits) || start > end {\n    return fmt.Errorf(\"invalid commit range %d..%d of %d commits\", start, end, len(commits))\n}\nerr := rebaseCmd.BeginInteractiveRebaseForCommitRange(commits, start, end, false)","handlingStrategy":"validation","validationCode":"if start < 0 || end < start || end >= len(commits) {\n    return fmt.Errorf(\"range %d..%d invalid for %d commits\", start, end, len(commits))\n}\nreturn rebaseCmd.BeginInteractiveRebaseForCommitRange(commits, start, end, keepEmpty)","typeGuard":null,"tryCatchPattern":"On 'index outside of range of commits', refresh commits and recompute indexes exactly once; a second failure means the caller's model plumbing is wrong — fix that, don't retry.","preventionTips":["Derive start/end from the commits slice passed in, never from a cached selection","Refresh after rebase/completion callbacks before allowing new selections","Unit-test index math against 0-, 1-, and N-length commit slices"],"tags":["internal","index-out-of-range","rebase","model-staleness"],"backgroundTag":null,"analyzedSha":"c477a2959b229fbf3284be0d4d2904ab61ec3c94","analyzedAt":"2026-08-15T08:34:32.451Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}