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

User cancelled dialog.

Error message

User cancelled dialog.

What it means

Thrown by DeviceCodeCommand.ExecuteAsync when the device-code dialog is dismissed without confirmation. The abstract ShowAsync presents the device-code UI; if the user closes it, WindowResult is false and the command throws instead of returning a result. This is a deliberate cancellation signal surfaced through Trace2 tracing.

Solutions

  1. Catch the Trace2Exception and handle it as a cancellation (return a cancelled exit code)
  2. Avoid showing the dialog in non-interactive environments (set GCM_INTERACTIVE=never or equivalent)
  3. Use a non-interactive authentication mode such as PAT via environment variables or credential store instead of the device-code UI
  4. Complete the device-code flow in the dialog instead of closing it

Example fix

// before
await command.ExecuteAsync();
// after
try { await command.ExecuteAsync(); }
catch (Trace2Exception ex) when (ex.Message.Contains("cancelled"))
{
    return ExitCode.Cancelled; // user closed the device-code dialog
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Skip the device-code UI when no interactive session is available
if (!Environment.UserInteractive || Environment.GetEnvironmentVariable("GCM_INTERACTIVE") == "never")
{
    throw new InvalidOperationException("Device-code flow requires an interactive session; use a PAT instead.");
}

Try / catch

try
{
    await deviceCodeCommand.ExecuteAsync();
}
catch (Trace2Exception ex) when (ex.Message.Contains("User cancelled dialog"))
{
    return ExitCode.Cancelled;
}

Prevention

When it happens

Trigger: Executing the device-code authentication command; the user closes the device-code window, hits Cancel/Esc, or the dialog fails to submit before ShowAsync returns with WindowResult == false.

Common situations: CI jobs with no interactive user show the dialog and it gets dismissed or orphaned; users close the window thinking it is not needed; automation frameworks kill the dialog window.

Related errors


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

Appendix: source

Thrown at src/Core/UI/Commands/DeviceCodeCommand.cs:39

            this.SetHandler(ExecuteAsync, code, url, noLogo);
        }

        private async Task<int> ExecuteAsync(string code, string url, bool noLogo)
        {
            var viewModel = new DeviceCodeViewModel(Context.SessionManager)
            {
                UserCode = code,
                VerificationUrl = url,
            };

            viewModel.ShowProductHeader = !noLogo;

            await ShowAsync(viewModel, CancellationToken.None);

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

            return 0;
        }

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

View on GitHub (pinned to e8ce762cd0)