git-ecosystem/git-credential-manager · error · ArgumentOutOfRangeException

At least one must be supplied

Error message

At least one {nameof(AuthenticationModes)} must be supplied

What it means

GitLabAuthentication.GetAuthenticationViaTtyAsync handles terminal (TTY) authentication prompts; when handed AuthenticationModes.None it cannot present any prompt and throws ArgumentOutOfRangeException with this message. It is reached from GetAuthenticationAsync when GUI prompts are disabled and the flow falls back to the terminal.

Solutions

  1. Configure at least one TTY-compatible auth mode (e.g. Pat) via credential.gitLabAuthModes / GCM_GITLAB_AUTHMODES.
  2. Supply a PAT so the terminal flow can use it without prompting: 'git credential approve' or GCM env credentials.
  3. Do not pass AuthenticationModes.None into the API; compute modes from available capabilities before calling.
  4. Enable GUI prompts (run within a desktop session) if Browser mode is the only intended option.

Example fix

// before (headless CI, no usable mode)
GCM_GITLAB_AUTHMODES=browser git-credential-manager get

// after
GCM_GITLAB_AUTHMODES=pat git-credential-manager get  // with a PAT available
Defensive patterns

Strategy: validation

Validate before calling

if (modes == AuthenticationModes.None)
{
    modes = AuthenticationModes.Pat; // ensure a TTY-promptable mode before calling the TTY flow
}

Try / catch

try
{
    var result = await gitLabAuth.GetAuthenticationAsync(targetUri, userName, modes);
}
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "modes")
{
    // recompute modes (at least Pat) and retry
}

Prevention

When it happens

Trigger: GetAuthenticationAsync falls back to GetAuthenticationViaTtyAsync (no GUI/desktop session or prompts disabled) while the effective modes value is None; also direct calls passing AuthenticationModes.None.

Common situations: Headless CI with GCM_INTERACTIVE disabled and gitLabAuthModes restricting to an unavailable mode; misconfiguration leaving no selectable TTY auth mode; programmatic misuse of the API.

Understand the failure class

Related errors


AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11). Data as JSON: /api/errors/9ef9ca0c635086b0. Report an issue: GitHub.

Appendix: source

Thrown at src/GitLab/GitLabAuthentication.cs:177

                    Context.Console.WriteLine($"Enter GitLab credentials for '{targetUri}'...");

                    if (string.IsNullOrWhiteSpace(userName))
                    {
                        userName = await TerminalPrompts.CreateText("Username").ShowAsync(Context.Console);
                    }
                    else
                    {
                        Context.Console.WriteLine($"Username: {userName}");
                    }

                    string token = await TerminalPrompts.CreateSecret("Personal access token").ShowAsync(Context.Console);
                    return new AuthenticationPromptResult(AuthenticationModes.Pat, new GitCredential(userName, token));

                case AuthenticationModes.Browser:
                    return new AuthenticationPromptResult(AuthenticationModes.Browser);

                case AuthenticationModes.None:
                    throw new ArgumentOutOfRangeException(nameof(modes),
                        @$"At least one {nameof(AuthenticationModes)} must be supplied");

                default:
                    var promptTitle = $"Select an authentication method for '{targetUri}'";
                    var prompt = TerminalPrompts.CreateSelection<AuthenticationModes>()
                        .Title(promptTitle);

                    if ((modes & AuthenticationModes.Browser) != 0) prompt.AddChoice("Web browser", AuthenticationModes.Browser);
                    if ((modes & AuthenticationModes.Pat) != 0) prompt.AddChoice("Personal access token", AuthenticationModes.Pat);
                    if ((modes & AuthenticationModes.Basic) != 0) prompt.AddChoice("Username/password", AuthenticationModes.Basic);

                    AuthenticationModes choice = await prompt.ShowAsync(Context.Console);

                    if (choice == AuthenticationModes.Browser) goto case AuthenticationModes.Browser;
                    if (choice == AuthenticationModes.Basic) goto case AuthenticationModes.Basic;
                    if (choice == AuthenticationModes.Pat) goto case AuthenticationModes.Pat;

                    throw new Exception();

View on GitHub (pinned to e8ce762cd0)