{"record":{"id":"bab5c5f9d7aa46a5","repo":"gitbutlerapp/gitbutler","slug":"authorization-process-aborted-by-user","errorCode":null,"errorMessage":"Authorization process aborted by user.","messagePattern":"Authorization process aborted by user\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/but/src/command/config.rs","lineNumber":1086,"sourceCode":"\n    writeln!(inout, \"Authentication successful! Welcome, {login}.\")?;\n    Ok(())\n}\n\n/// Authenticate with GitHub using the device OAuth flow\nasync fn github_oauth(mut inout: InputOutputChannel<'_>) -> Result<()> {\n    let code = but_api::github::init_github_device_oauth().await?;\n    writeln!(\n        inout,\n        \"Device authorization initiated. Please visit the following URL and enter the code:\\n\\nhttps://github.com/login/device\\n\\nCode: {}\\n\\n\",\n        code.user_code\n    )?;\n\n    if inout.confirm_no_default(\n        \"After completing authorization in your browser, press 'y' to continue.\",\n    )? != ConfirmOrEmpty::Yes\n    {\n        anyhow::bail!(\"Authorization process aborted by user.\")\n    }\n\n    let status = but_api::github::check_github_auth_status(code.device_code)\n        .await\n        .map_err(|err| err.context(\"Authentication failed\"))?;\n\n    writeln!(\n        inout,\n        \"Authentication successful! Welcome, {}.\",\n        status.login\n    )?;\n\n    Ok(())\n}\n\nasync fn display_authenticated_github_accounts(\n    known_gh_accounts: &Vec<but_github::GithubAccountIdentifier>,\n    out: &mut dyn Write,","sourceCodeStart":1068,"sourceCodeEnd":1104,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but/src/command/config.rs#L1068-L1104","documentation":"During GitHub OAuth device-flow authentication, the CLI prints a code, opens the browser, and then blocks on a y/n confirmation asking the user to press 'y' after completing authorization in the browser. If the user enters anything other than 'y' (e.g. 'n', Enter for empty, or EOF on a piped stdin), the flow is treated as intentionally aborted and github_auth bails with this message before polling auth status.","triggerScenarios":"During `but auth github` (github_oauth): pressing Enter/n at the \"press 'y' to continue\" prompt, closing stdin (Ctrl+D), or running the command non-interactively so confirm_no_default receives no 'y'.","commonSituations":"Running the CLI inside a script or CI where stdin is not a TTY; user abandoning login halfway; confusion about needing to press 'y' after browser auth rather than just Enter.","solutions":["Re-run the auth command and answer 'y' after completing authorization in the browser","Ensure the command runs in an interactive terminal so the confirmation prompt can be answered","Complete the browser authorization step before confirming; if the browser step failed, restart the whole device-flow login"],"exampleFix":"// before (non-interactive)\necho \"\" | but auth github\n// after\nbut auth github   # run interactively, answer 'y' after browser auth","handlingStrategy":"try-catch","validationCode":"const isInteractive = process.stdin.isTTY;\nif (!isInteractive) throw new Error('GitHub OAuth login requires an interactive terminal');","typeGuard":"const isAbortError = (e) => e instanceof Error && /aborted by user/i.test(e.message);","tryCatchPattern":"try {\n  await runGithubAuth();\n} catch (e) {\n  if (isAbortError(e)) {\n    console.log('Login cancelled; re-run to try again.');\n  } else throw e;\n}","preventionTips":["Run auth commands in a TTY, never with piped/redirected stdin","Complete the browser step before answering the confirmation","Know that anything except 'y' at the prompt cancels the flow"],"tags":["oauth","cli","authentication"],"backgroundTag":"operation-aborted-by-user","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}