{"record":{"id":"00e568a07c49c19b","repo":"Devolutions/UniGetUI","slug":"github-sign-in-did-not-complete-successfully-fini","errorCode":null,"errorMessage":"GitHub sign-in did not complete successfully. Finish the device authorization and try again.","messagePattern":"GitHub sign-in did not complete successfully\\. Finish the device authorization and try again\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/UniGetUI.Interface.IpcApi/IpcBackupApi.cs","lineNumber":250,"sourceCode":"            var user = await userClient.GetCurrentUserAsync();\n            Settings.SetValue(Settings.K.GitHubUserLogin, user.Login ?? string.Empty);\n            ClearPendingGitHubDeviceFlow();\n\n            return new IpcGitHubAuthResult\n            {\n                Status = \"success\",\n                Command = \"complete-github-sign-in\",\n                Message = string.IsNullOrWhiteSpace(user.Login)\n                    ? \"GitHub sign-in completed.\"\n                    : $\"GitHub sign-in completed for {user.Login}.\",\n                Auth = await GetGitHubAuthInfoAsync(),\n            };\n        }\n        catch (Exception ex)\n        {\n            Logger.Error(\"An error occurred while completing GitHub device flow sign-in:\");\n            Logger.Error(ex);\n            throw new InvalidOperationException(\n                \"GitHub sign-in did not complete successfully. Finish the device authorization and try again.\"\n            );\n        }\n    }\n\n    public static async Task<IpcGitHubAuthResult> SignOutGitHubAsync()\n    {\n        Settings.SetValue(Settings.K.GitHubUserLogin, \"\");\n        SecureGHTokenManager.DeleteToken();\n        ClearPendingGitHubDeviceFlow();\n\n        return new IpcGitHubAuthResult\n        {\n            Status = \"success\",\n            Command = \"sign-out-github\",\n            Message = \"GitHub sign-out complete.\",\n            Auth = await GetGitHubAuthInfoAsync(),\n        };","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/Devolutions/UniGetUI/blob/9b1d7d0eab91620fc15c86b36676532095936ae3/src/UniGetUI.Interface.IpcApi/IpcBackupApi.cs#L232-L268","documentation":"CompleteGitHubDeviceFlowAsync wraps the token-exchange and user-fetch logic in a try/catch (Exception). If any exception occurs inside the try block — HttpRequestException from the token endpoint, the empty-token InvalidOperationException, an error from GetCurrentUserAsync, or a SecureGHTokenManager failure — it is logged and re-thrown as a new InvalidOperationException with this generic message. The original exception's type and detail are lost to the caller (only logged).","triggerScenarios":"Any exception is thrown within the try block of CompleteGitHubDeviceFlowAsync: network failure contacting GitHub, expired/revoked token, empty access token, failure to fetch the current user, or an error storing the token securely. The catch-all wraps all of these into a single generic message.","commonSituations":"Transient network error during token exchange. The user did not complete authorization and the token endpoint returned an error. The stored token was invalid. GetCurrentUserAsync failed with 401/403. The original root cause must be found in the logs (Logger.Error) since the re-thrown exception does not preserve it as InnerException.","solutions":["Check the application logs (Logger.Error output) for the original exception that was swallowed — the re-thrown message is generic.","Retry the complete flow; most causes (network, timing) are transient.","Restart the device flow (StartGitHubDeviceFlowAsync) if retries fail, in case the device code or token is stale.","Verify network connectivity and that UNIGETUI_GITHUB_CLIENT_ID is correctly configured."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await IpcBackupApi.CompleteGitHubDeviceFlowAsync(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"did not complete successfully\"))\n{ /* inspect logs for the original swallowed exception; restart the flow */ }","preventionTips":["Check Logger.Error output for the root cause — the re-thrown exception hides it.","Restart the device flow if the generic completion error persists.","Verify network connectivity and client-ID configuration before retrying."],"tags":["github","oauth","device-flow","authentication","error-handling","ipc"],"backgroundTag":null,"analyzedSha":"9b1d7d0eab91620fc15c86b36676532095936ae3","analyzedAt":"2026-08-13T12:19:18.278Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}