git-ecosystem/git-credential-manager · info · Trace2Exception

User cancelled dialog.

Error message

User cancelled dialog.

What it means

TwoFactorCommand's ExecuteAsync shows the two-factor code dialog during GitHub authentication. If the user cancels or closes the dialog (WindowResult false), it throws this Trace2Exception because the 2FA code required to continue authentication was not provided.

Solutions

  1. Re-run the git operation and enter the current 2FA code (from your authenticator app or SMS) in the dialog.
  2. Switch to an authentication mode that does not require legacy 2FA entry, such as browser OAuth or a PAT (which embeds 2FA at creation time).
  3. Prefer modern flows: GitHub's OAuth/device flows handle 2FA server-side, avoiding this dialog entirely.
  4. If prompted repeatedly, update GCM to a version that uses OAuth instead of basic-auth + 2FA prompts.

Example fix

// before (basic auth triggers 2FA dialog)
git-credential-manager github login

// after (OAuth/device flow handles 2FA server-side)
git-credential-manager github login --browser
// or use a PAT created with SSO/2FA satisfied
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    await twoFactorCommand.ExecuteAsync(input, output);
}
catch (Exception ex) when (ex.Message == "User cancelled dialog.")
{
    // retry with OAuth/browser flow where 2FA is handled server-side
}

Prevention

When it happens

Trigger: GitHub authentication with an account/app that requires two-factor authentication; the 2FA entry dialog is shown and the user closes it without entering a code.

Common situations: Users without their 2FA device at hand; confusion about which 2FA code (TOTP vs SMS) to enter; automation dismissing the dialog.

Related errors


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

Appendix: source

Thrown at src/GitHub/UI/Commands/TwoFactorCommand.cs:33

        {
            var sms = new Option<bool>("--sms", "Two-factor code was sent via SMS.");
            AddOption(sms);

            this.SetHandler(ExecuteAsync, sms);
        }

        private async Task<int> ExecuteAsync(bool sms)
        {
            var viewModel = new TwoFactorViewModel(Context.SessionManager, Context.ProcessManager)
            {
                IsSms = sms
            };

            await ShowAsync(viewModel, CancellationToken.None);

            if (!viewModel.WindowResult)
            {
                throw new Trace2Exception(Context.Trace2, "User cancelled dialog.");
            }

            WriteResult(new Dictionary<string, string>
            {
                ["code"] = viewModel.Code
            });

            return 0;
        }

        protected abstract Task ShowAsync(TwoFactorViewModel viewModel, CancellationToken ct);
    }
}

View on GitHub (pinned to e8ce762cd0)