jesseduffield/lazygit · error
Password, passphrase and/or username wrong
Error message
Password, passphrase and/or username wrong
What it means
Returned by FilesController.fetch when a 'git fetch' subprocess fails with exit status 128. The code pattern-matches the error string for 'exit status 128' (git's generic fatal code) and assumes an authentication failure, surfacing Tr.PassUnameWrong ('Password, passphrase and/or username wrong'). Because 128 covers any fatal git error, the message is a heuristic, not a diagnosis: the real cause (often remote auth) is swallowed and only visible in lazygit's command log.
Source
Thrown at pkg/gui/controllers/files_controller.go:1543
},
AllowEmptyInput: true,
})
return nil
}
func (self *FilesController) onClickMain(opts gocui.ViewMouseBindingOpts) error {
return self.EnterFile(types.OnFocusOpts{ClickedWindowName: "main", ClickedViewLineIdx: opts.Y})
}
func (self *FilesController) fetch() error {
fetchGeneration := self.c.State().GetRepoGeneration()
return self.c.WithWaitingStatus(self.c.Tr.FetchingStatus, func(task gocui.Task) error {
self.c.LogAction("Fetch")
err := self.c.Git().Sync.Fetch(task)
if err != nil && strings.Contains(err.Error(), "exit status 128") {
return errors.New(self.c.Tr.PassUnameWrong)
}
return self.c.Helpers().BranchesHelper.PostFetchRefresh(err, false, fetchGeneration)
})
}
// Couldn't think of a better term than 'normalised'. Alas.
// The idea is that when you select a range of nodes, you will often have both
// a node and its parent node selected. If we are trying to discard changes to the
// selected nodes, we'll get an error if we try to discard the child after the parent.
// So we just need to filter out any nodes from the selection that are descendants
// of other nodes
func normalisedSelectedNodes(selectedNodes []*filetree.FileNode) []*filetree.FileNode {
return lo.Filter(selectedNodes, func(node *filetree.FileNode, _ int) bool {
return !isDescendentOfSelectedNodes(node, selectedNodes)
})
}
View on GitHub (pinned to c477a2959b)
Solutions
- Run the same fetch outside lazygit (git fetch -v) to see the real stderr that lazygit discarded.
- For HTTPS: verify/update credentials via your credential helper (e.g. git credential reject, or update the PAT).
- For SSH: run ssh -T git@host to test auth, ensure the key is in ssh-agent (ssh-add) and GIT_SSH_COMMAND points at the right key.
- Check the remote URL with git remote -v for typos or wrong scheme.
- Confirm this is really auth and not another fatal error; exit 128 alone does not prove wrong credentials.
Example fix
// before (heuristic that mislabels any exit-128 fetch failure):
if err != nil && strings.Contains(err.Error(), "exit status 128") {
return errors.New(self.c.Tr.PassUnameWrong)
}
// after (surface the underlying error, annotate with the auth hint):
if err != nil {
if strings.Contains(err.Error(), "exit status 128") {
return fmt.Errorf("%w: %s", err, self.c.Tr.PassUnameWrong)
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before relying on the message, verify auth yourself:
// out, err := exec.Command("git", "fetch", "--dry-run").CombinedOutput()
// inspect out for 'Authentication failed' / 'Permission denied' Try / catch
if err := controller.fetch(); err != nil {
if err.Error() == c.Tr.PassUnameWrong {
// treat as auth failure, but re-run `git fetch -v` externally for the real stderr
}
} Prevention
- Pre-verify remote auth with 'ssh -T git@host' or a credential-helper probe before long lazygit sessions
- Keep SSH keys in the agent (ssh-add) so non-interactive fetches never prompt
- Avoid reading the message as proof of wrong credentials; exit 128 is generic
When it happens
Trigger: Pressing the fetch keybinding (default 'f') in the Files panel while the remote rejects credentials: wrong HTTPS password, expired PAT, missing/locked SSH key, or a passphrase prompt that cannot be answered in lazygit's headless subprocess. Also fires for unrelated fatal fetch errors (bad URL, DNS failure, proxy error) since the check only tests the exit code.
Common situations: Expired GitHub/GitLab personal access token; SSH key not added to ssh-agent so authentication fails non-interactively; credential helper misconfigured or missing; typo'd remote URL; corporate proxy blocking the remote. Common right after credential rotation or on a new machine without configured keys.
Related errors
- upstream branch %s/%s not found. If you expect it to exist,
- Git version must be at least %s. Please upgrade your git ver
- Lazygit does not support bare repos.
- unexpected git output
- Must specify a remote if specifying a branch
AI-assisted analysis of jesseduffield/lazygit@c477a2959b (2026-08-15).
Data as JSON: /api/errors/82a6f21c40c694d9.
Report an issue: GitHub.