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
- Configure at least one TTY-compatible auth mode (e.g. Pat) via credential.gitLabAuthModes / GCM_GITLAB_AUTHMODES.
- Supply a PAT so the terminal flow can use it without prompting: 'git credential approve' or GCM env credentials.
- Do not pass AuthenticationModes.None into the API; compute modes from available capabilities before calling.
- 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
- Configure a TTY-compatible mode (Pat) in credential.gitLabAuthModes for headless runs
- Supply a GitLab PAT before disabling interactive prompts
- Validate modes != None before invoking authentication
- Avoid restricting auth modes to GUI-only options in CI
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
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Unknown authentication mode
- At least one AuthenticationModes must be supplied
- Unexpected AuthenticationModes returned from prompt
- Unexpected interaction mode.
- Must specify at least one
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)