{"record":{"id":"f922c084fd094151","repo":"git-ecosystem/git-credential-manager","slug":"user-cancelled-dialog-f922c0","errorCode":null,"errorMessage":"User cancelled dialog.","messagePattern":"User cancelled dialog\\.","errorType":"exception","errorClass":"Trace2Exception","httpStatus":null,"severity":"info","filePath":"src/Core/UI/Commands/OAuthCommand.cs","lineNumber":55,"sourceCode":"\n            if (!string.IsNullOrWhiteSpace(title))\n            {\n                viewModel.Title = title;\n            }\n\n            viewModel.Description = !string.IsNullOrWhiteSpace(resource)\n                ? $\"Sign in to '{resource}'\"\n                : \"Select a sign-in option\";\n\n            viewModel.ShowBrowserLogin = browser;\n            viewModel.ShowDeviceCodeLogin = deviceCode;\n            viewModel.ShowProductHeader = !noLogo;\n\n            await ShowAsync(viewModel, CancellationToken.None);\n\n            if (!viewModel.WindowResult)\n            {\n                throw new Trace2Exception(Context.Trace2, \"User cancelled dialog.\");\n            }\n\n            var result = new Dictionary<string, string>();\n            switch (viewModel.SelectedMode)\n            {\n                case OAuthAuthenticationModes.Browser:\n                    result[\"mode\"] = \"browser\";\n                    break;\n\n                case OAuthAuthenticationModes.DeviceCode:\n                    result[\"mode\"] = \"devicecode\";\n                    break;\n\n                default:\n                    throw new ArgumentOutOfRangeException();\n            }\n\n            WriteResult(result);","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/Core/UI/Commands/OAuthCommand.cs#L37-L73","documentation":"Thrown by OAuthCommand.ExecuteAsync when the OAuth mode-selection dialog is closed without a selection. After ShowAsync returns, a false WindowResult means the user never picked browser/device/PAT mode, so the command throws a Trace2Exception rather than proceeding with an undefined mode. It signals intentional user cancellation.","triggerScenarios":"Running the OAuth authentication command; user clicks Cancel, presses Esc, or closes the mode-selection window so viewModel.WindowResult is false when ShowAsync returns.","commonSituations":"Unattended CI runs where the OAuth dialog appears but nobody selects a mode; users abandoning the sign-in flow; a script terminating the dialog process window.","solutions":["Catch the Trace2Exception and treat it as cancellation rather than an auth failure","Prefer non-interactive auth (PAT in env var or credential store, GCM_INTERACTIVE=never) so the dialog never appears","Select an authentication mode and confirm the dialog to let the command proceed","Pre-seed credentials so GCM skips the interactive OAuth prompt entirely"],"exampleFix":"// before\nawait oauthCommand.ExecuteAsync();\n// after\ntry { await oauthCommand.ExecuteAsync(); }\ncatch (Trace2Exception ex) when (ex.Message == \"User cancelled dialog.\")\n{\n    Environment.ExitCode = (int)ExitCode.Cancelled;\n}","handlingStrategy":"try-catch","validationCode":"// Ensure an interactive session before launching the OAuth mode dialog\nif (Environment.GetEnvironmentVariable(\"GCM_INTERACTIVE\") == \"never\" || !Environment.UserInteractive)\n{\n    Console.Error.WriteLine(\"OAuth dialog requires interactivity; configure credentials non-interactively.\");\n    return ExitCode.NonInteractive;\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    await oauthCommand.ExecuteAsync();\n}\ncatch (Trace2Exception ex) when (ex.Message == \"User cancelled dialog.\")\n{\n    Environment.ExitCode = (int)ExitCode.Cancelled;\n}","preventionTips":["Prefer non-interactive OAuth (stored tokens/PATs) in automation","Treat 'User cancelled dialog.' Trace2Exception as a normal cancellation path","Pre-select auth mode via configuration so the selection dialog can be skipped","Retry prompts are useless after cancellation — do not auto-retry this error"],"tags":["ui","dialog","cancellation","oauth"],"backgroundTag":"user-cancelled-dialog","analyzedSha":"e8ce762cd04b4100ae637b5fbf39ef9d0a96561e","analyzedAt":"2026-09-11T17:15:08.753Z","contentChangedAt":"2026-09-11T17:15:08.753Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}