git-ecosystem/git-credential-manager · error · Trace2InvalidOperationException
Browser authentication requires a desktop session
Error message
Browser authentication requires a desktop session
What it means
Git Credential Manager's browser (OAuth2) authentication flow for GitHub requires the ability to launch the user's default web browser. Before starting the flow, GetOAuthTokenViaBrowserAsync checks Context.SessionManager.IsWebBrowserAvailable, and if the process is running headless (no desktop session / no discoverable browser) it throws this Trace2InvalidOperationException instead of attempting an impossible browser launch.
Solutions
- Use a non-browser authentication mode instead: a Personal Access Token (GCM_AUTH_PAT / 'git-credential-manager github login --pat') or device-code flow.
- Run the git/GCM command inside a desktop session where a default browser is registered and detectable.
- Set GCM_INTERACTIVE (or GcmInteractive) to false so GCM picks a non-interactive flow, or pre-seed credentials in the store.
- If on WSL/headless, configure the environment so a browser can be opened (e.g. wslu/browser wrapper) or forward credentials from the Windows host.
Example fix
// before git-credential-manager github login --browser // on headless CI runner // after git-credential-manager github login --pat // or set GITHUB_TOKEN / use device flow
Defensive patterns
Strategy: validation
Validate before calling
if (Environment.UserInteractive == false || string.IsNullOrEmpty(Environment.GetEnvironmentVariable("DISPLAY")) && Environment.OSVersion.Platform != PlatformID.Win32NT)
{
// fall back to PAT or device-code flow instead of browser auth
return AuthenticateViaPatOrDeviceCode();
} Try / catch
try
{
var token = await githubAuth.GetOAuthTokenViaBrowserAsync(targetUri, scopes);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("desktop session"))
{
token = await githubAuth.GetOAuthTokenViaDeviceCodeAsync(targetUri, scopes);
} Prevention
- Check for a desktop session/browser availability before choosing browser auth
- Default to PAT or device-code auth in CI, containers, and SSH environments
- Set GCM_INTERACTIVE=Never in headless automation
- Pre-seed credentials with 'git credential approve' for non-interactive runs
When it happens
Trigger: Calling GetOAuthTokenViaBrowserAsync (e.g. via 'git-credential-manager github login --browser' or GCM choosing Browser auth) on a machine where IsWebBrowserAvailable is false: SSH sessions, CI runners, containers, Windows/SSH servers without a GUI, or environments where SessionManager cannot detect a desktop session.
Common situations: Running git push/pull with GCM over SSH into a headless Linux box; CI pipelines that force browser auth instead of PAT/OAuth-device; Docker containers performing credential acquisition interactively; WSL configurations without a browser forwarding setup.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- No available interaction modes.
- No authentication mode selected!
- Missing 'mode' in response
- Missing 'pat' in response
- Missing 'username' in response
AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11).
Data as JSON: /api/errors/c475d42201cbb72b.
Report an issue: GitHub.
Appendix: source
Thrown at src/GitHub/GitHubAuthentication.cs:418
if (!resultDict.TryGetValue("code", out string authCode))
{
throw new Trace2Exception(Context.Trace2, "Missing 'code' in response");
}
return authCode;
}
public async Task<OAuth2TokenResult> GetOAuthTokenViaBrowserAsync(Uri targetUri, IEnumerable<string> scopes, string loginHint)
{
ThrowIfUserInteractionDisabled();
var oauthClient = new GitHubOAuth2Client(HttpClient, Context.Settings, targetUri, Context.Trace2);
// Can we launch the user's default web browser?
if (!Context.SessionManager.IsWebBrowserAvailable)
{
throw new Trace2InvalidOperationException(Context.Trace2,
"Browser authentication requires a desktop session");
}
var browserOptions = new OAuth2WebBrowserOptions
{
SuccessResponseHtml = GitHubResources.AuthenticationResponseSuccessHtml,
FailureResponseHtmlFormat = GitHubResources.AuthenticationResponseFailureHtmlFormat
};
var browser = new OAuth2SystemWebBrowser(Context.SessionManager, browserOptions);
// If we have a login hint we should pass this to GitHub as an extra query parameter
IDictionary<string, string> queryParams = null;
if (loginHint != null)
{
queryParams = new Dictionary<string, string>
{
["login"] = loginHint
};View on GitHub (pinned to e8ce762cd0)