git-ecosystem/git-credential-manager · error · Trace2Exception
Missing 'mode' in response
Error message
Missing 'mode' in response
What it means
Thrown by GetAuthenticationViaHelperAsync in GitLabAuthentication when the external Git credential helper command returns a result dictionary that does not contain a 'mode' key. The helper protocol requires every response to declare its authentication mode (pat, browser, or basic); without it GCM cannot decide how to proceed and fails fast with a Trace2Exception.
Solutions
- Update or fix the configured GitLab credential helper so it emits `mode=` (one of pat, browser, basic) in its output.
- Check the helper command configured via `credential.gitLabHelper` / GCM_GITLAB_HELPER and remove any broken override so GCM falls back to its built-in UI flow.
- Inspect helper stdout for stray log lines that break key=value parsing; redirect logging to stderr.
Example fix
// before (helper script output) echo "pat=ghp_xxx" // after echo "mode=pat" echo "pat=glpat_xxx"
Defensive patterns
Strategy: validation
Validate before calling
// Validate helper output before relying on it
class HelperResponseValidator {
static bool HasMode(IDictionary<string, string> result) =>
result != null && result.ContainsKey("mode") &&
new[] { "pat", "browser", "basic" }.Contains(result["mode"].ToLowerInvariant());
} Try / catch
try {
var result = await auth.GetAuthenticationAsync(...);
} catch (Trace2Exception ex) when (ex.Message.Contains("Missing 'mode' in response")) {
// fall back to built-in UI flow or prompt user to fix the helper
logger.Warn("GitLab helper returned no mode; using built-in auth");
} Prevention
- Pin the helper script to the documented GCM helper protocol (mode + fields)
- Test custom helpers manually by inspecting their key=value stdout
- Avoid printing logs to stdout in helper scripts
When it happens
Trigger: Running `git-credential-manager gitlab` (GetAuthenticationAsync -> GetAuthenticationViaHelperAsync) where the configured helper executable (GitLabHelper.Command setting, e.g. a custom script) exits successfully but emits output without a `mode=` line.
Common situations: Custom or third-party GitLab credential helpers that print only a token; outdated helper scripts written for an older protocol; helper output parsed incorrectly due to extra logging polluting stdout.
Related errors
- Missing 'username' in response
- Missing 'password' in response
- Missing 'pat' in response
- Missing 'username' in response
- Missing 'password' in response
AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11).
Data as JSON: /api/errors/7c2609433a909c3f.
Report an issue: GitHub.
Appendix: source
Thrown at src/GitLab/GitLabAuthentication.cs:219
{
var promptArgs = new StringBuilder(args);
promptArgs.Append("prompt");
if (!string.IsNullOrWhiteSpace(userName))
{
promptArgs.AppendFormat(" --username {0}", QuoteCmdArg(userName));
}
promptArgs.AppendFormat(" --url {0}", QuoteCmdArg(targetUri.ToString()));
if ((modes & AuthenticationModes.Basic) != 0) promptArgs.Append(" --basic");
if ((modes & AuthenticationModes.Browser) != 0) promptArgs.Append(" --browser");
if ((modes & AuthenticationModes.Pat) != 0) promptArgs.Append(" --pat");
IDictionary<string, string> resultDict = await InvokeHelperAsync(helperCommand, promptArgs.ToString());
if (!resultDict.TryGetValue("mode", out string responseMode))
{
throw new Trace2Exception(Context.Trace2, "Missing 'mode' in response");
}
switch (responseMode.ToLowerInvariant())
{
case "pat":
if (!resultDict.TryGetValue("pat", out string pat))
{
throw new Trace2Exception(Context.Trace2, "Missing 'pat' in response");
}
if (!resultDict.TryGetValue("username", out string patUserName))
{
// Username is optional for PATs
}
return new AuthenticationPromptResult(
AuthenticationModes.Pat, new GitCredential(patUserName, pat));
View on GitHub (pinned to e8ce762cd0)