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

  1. Use a non-browser authentication mode instead: a Personal Access Token (GCM_AUTH_PAT / 'git-credential-manager github login --pat') or device-code flow.
  2. Run the git/GCM command inside a desktop session where a default browser is registered and detectable.
  3. Set GCM_INTERACTIVE (or GcmInteractive) to false so GCM picks a non-interactive flow, or pre-seed credentials in the store.
  4. 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

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.

Related errors


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)