{"record":{"id":"510d49155d80b350","repo":"git-ecosystem/git-credential-manager","slug":"failed-to-enumerate-git-remotes","errorCode":null,"errorMessage":"Failed to enumerate Git remotes","messagePattern":"Failed to enumerate Git remotes","errorType":"exception","errorClass":"Trace2Exception","httpStatus":null,"severity":"error","filePath":"src/Core/Git.cs","lineNumber":197,"sourceCode":"                // Redirect stderr so we can check for 'not a git repository' errors\n                git.StartInfo.RedirectStandardError = true;\n                git.Start(Trace2ProcessClass.Git);\n                // To avoid deadlocks, always read the output stream first and then wait\n                // TODO: don't read in all the data at once; stream it\n                string data = git.StandardOutput.ReadToEnd();\n                string stderr = git.StandardError.ReadToEnd();\n                git.WaitForExit();\n\n                switch (git.ExitCode)\n                {\n                    case 0: // OK\n                        break;\n                    case 128 when stderr.Contains(\"not a git repository\"): // Not inside a Git repository\n                        yield break;\n                    default:\n                        var message = \"Failed to enumerate Git remotes\";\n                        _trace.WriteLine($\"{message} (exit={git.ExitCode})\");\n                        throw CreateGitException(git, message, _trace2);\n                }\n\n                string[] lines = data.Split('\\n');\n\n                // Remotes are always output in groups of two (fetch and push)\n                for (int i = 0; i + 1 < lines.Length; i += 2)\n                {\n                    // The fetch URL is written first, followed by the push URL\n                    string[] fetchLine = lines[i].Split();\n                    string[] pushLine = lines[i + 1].Split();\n\n                    // Remote name is always first (and should match between fetch/push)\n                    string remoteName = fetchLine[0];\n\n                    // The next part, if present, is the URL\n                    string fetchUrl = null;\n                    string pushUrl = null;\n                    if (fetchLine.Length > 1 && !string.IsNullOrWhiteSpace(fetchLine[1])) fetchUrl = fetchLine[1].TrimEnd();","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/Core/Git.cs#L179-L215","documentation":"Thrown by Git.GetRemotes when `git remote -v` exits with an unexpected code. Exit 128 with 'not a git repository' in stderr is handled gracefully (yields nothing), so this error signals a different git failure while enumerating remotes, such as a corrupted config or a failing git executable.","triggerScenarios":"Calling GetRemotes (or the `remotes` property) in a repository where `git remote -v` fails with a code other than 0 or the handled 128/not-a-repository case — corrupted .git/config, unreadable repo, broken git install.","commonSituations":"Manually edited or corrupt .git/config with malformed remote sections; repository on a failing disk; git version too old to parse the config.","solutions":["Run `git remote -v` manually to see the underlying git error","Validate and repair .git/config (remove malformed [remote] sections or run `git config --local --list`)","Run `git fsck` to check repository integrity","Confirm `git --version` works and the binary is not corrupted"],"exampleFix":"// before\nforeach (var r in git.GetRemotes()) { ... } // throws on corrupt config\n// after\nIEnumerable<GitRemote> remotes;\ntry { remotes = git.GetRemotes(); }\ncatch (GitException) { remotes = Enumerable.Empty<GitRemote>(); }","handlingStrategy":"try-catch","validationCode":"var probe = Process.Run(\"git\", \"remote -v\", workingDir);\nbool remotesReadable = probe.ExitCode == 0 || (probe.ExitCode == 128 && probe.Stderr.Contains(\"not a git repository\"));","typeGuard":"bool TryGetRemotes(Git git, out IReadOnlyList<GitRemote> remotes) { try { remotes = git.GetRemotes().ToList(); return true; } catch (GitException) { remotes = Array.Empty<GitRemote>(); return false; } }","tryCatchPattern":"try { foreach (var r in git.GetRemotes()) YieldRemote(r); }\ncatch (GitException ex) { log.Warn($\"Remote enumeration failed: {ex.Message}\"); }","preventionTips":["Do not hand-edit .git/config while the app runs; use git config commands","Validate config syntax after scripted edits with `git config --local --list`","Keep the repo free of disk errors (`git fsck`)","Check remotes only inside directories that pass IsInsideRepository"],"tags":["git","remotes","process"],"backgroundTag":"git-command-failed","analyzedSha":"e8ce762cd04b4100ae637b5fbf39ef9d0a96561e","analyzedAt":"2026-09-11T17:15:08.753Z","contentChangedAt":"2026-09-11T17:15:08.753Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}