{"record":{"id":"82a6f21c40c694d9","repo":"jesseduffield/lazygit","slug":"password-passphrase-and-or-username-wrong","errorCode":null,"errorMessage":"Password, passphrase and/or username wrong","messagePattern":"Password, passphrase and/or username wrong","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gui/controllers/files_controller.go","lineNumber":1543,"sourceCode":"\t\t},\n\t\tAllowEmptyInput: true,\n\t})\n\n\treturn nil\n}\n\nfunc (self *FilesController) onClickMain(opts gocui.ViewMouseBindingOpts) error {\n\treturn self.EnterFile(types.OnFocusOpts{ClickedWindowName: \"main\", ClickedViewLineIdx: opts.Y})\n}\n\nfunc (self *FilesController) fetch() error {\n\tfetchGeneration := self.c.State().GetRepoGeneration()\n\treturn self.c.WithWaitingStatus(self.c.Tr.FetchingStatus, func(task gocui.Task) error {\n\t\tself.c.LogAction(\"Fetch\")\n\t\terr := self.c.Git().Sync.Fetch(task)\n\n\t\tif err != nil && strings.Contains(err.Error(), \"exit status 128\") {\n\t\t\treturn errors.New(self.c.Tr.PassUnameWrong)\n\t\t}\n\n\t\treturn self.c.Helpers().BranchesHelper.PostFetchRefresh(err, false, fetchGeneration)\n\t})\n}\n\n// Couldn't think of a better term than 'normalised'. Alas.\n// The idea is that when you select a range of nodes, you will often have both\n// a node and its parent node selected. If we are trying to discard changes to the\n// selected nodes, we'll get an error if we try to discard the child after the parent.\n// So we just need to filter out any nodes from the selection that are descendants\n// of other nodes\nfunc normalisedSelectedNodes(selectedNodes []*filetree.FileNode) []*filetree.FileNode {\n\treturn lo.Filter(selectedNodes, func(node *filetree.FileNode, _ int) bool {\n\t\treturn !isDescendentOfSelectedNodes(node, selectedNodes)\n\t})\n}\n","sourceCodeStart":1525,"sourceCodeEnd":1561,"githubUrl":"https://github.com/jesseduffield/lazygit/blob/c477a2959b229fbf3284be0d4d2904ab61ec3c94/pkg/gui/controllers/files_controller.go#L1525-L1561","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (heuristic that mislabels any exit-128 fetch failure):\nif err != nil && strings.Contains(err.Error(), \"exit status 128\") {\n    return errors.New(self.c.Tr.PassUnameWrong)\n}\n\n// after (surface the underlying error, annotate with the auth hint):\nif err != nil {\n    if strings.Contains(err.Error(), \"exit status 128\") {\n        return fmt.Errorf(\"%w: %s\", err, self.c.Tr.PassUnameWrong)\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":"// Before relying on the message, verify auth yourself:\n// out, err := exec.Command(\"git\", \"fetch\", \"--dry-run\").CombinedOutput()\n// inspect out for 'Authentication failed' / 'Permission denied'","typeGuard":null,"tryCatchPattern":"if err := controller.fetch(); err != nil {\n    if err.Error() == c.Tr.PassUnameWrong {\n        // treat as auth failure, but re-run `git fetch -v` externally for the real stderr\n    }\n}","preventionTips":["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"],"tags":["git","authentication","fetch","error-mapping","network"],"backgroundTag":null,"analyzedSha":"c477a2959b229fbf3284be0d4d2904ab61ec3c94","analyzedAt":"2026-08-15T08:34:32.451Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}