{"record":{"id":"8f44ff218419e90a","repo":"gitbutlerapp/gitbutler","slug":"could-not-determine-which-forge-provider-to-authen","errorCode":null,"errorMessage":"Could not determine which forge provider to authenticate with","messagePattern":"Could not determine which forge provider to authenticate with","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"crates/but/src/command/config.rs","lineNumber":900,"sourceCode":"    }\n\n    let auth_options = nonempty::nonempty![\n        (\"GitHub\", ForgeProvider::GitHub),\n        (\"GitLab\", ForgeProvider::GitLab),\n        (\"Bitbucket\", ForgeProvider::Bitbucket)\n    ];\n    let selected_option = {\n        let mut input = out\n            .prepare_for_terminal_input()\n            .context(\"Human input required - run this in a terminal\")?;\n        input\n            .prompt_select(\n                \"Select a forge provider to authenticate with\",\n                &auth_options,\n            )?\n            .cloned()\n            .ok_or_else(|| {\n                anyhow::anyhow!(\"Could not determine which forge provider to authenticate with\")\n            })?\n    };\n\n    match selected_option {\n        ForgeProvider::GitHub => github_auth(out).await,\n        ForgeProvider::GitLab => gitlab_auth(out).await,\n        ForgeProvider::Bitbucket => bitbucket_auth(out).await,\n    }\n}\n\n/// Authenticate with Bitbucket Cloud using an Atlassian API token.\nasync fn bitbucket_auth(out: &mut OutputChannel) -> Result<()> {\n    use but_bitbucket::AuthStatusResponse;\n\n    let t = theme::get();\n    let mut inout = out\n        .prepare_for_terminal_input()\n        .context(\"Human input required - run this in a terminal\")?;","sourceCodeStart":882,"sourceCodeEnd":918,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but/src/command/config.rs#L882-L918","documentation":"During interactive forge authentication setup, the command opens a terminal picker (prompt_select) over the supported providers (GitHub/GitLab/Bitbucket) and this error fires when the picker returns no selection — i.e. the user cancelled (Esc/Ctrl-C path) or the picker produced zero picks. It is a user-cancellation guard, not a system failure; authentication simply cannot proceed without a provider choice.","triggerScenarios":"Running the forge auth command interactively and pressing Esc or aborting the fuzzy-finder picker; a picker session that exits without highlighting+confirming an entry.","commonSituations":"Users exploring `but config` menus and backing out with Esc; SSH sessions dropped mid-prompt; terminal emulators sending an escape keypress unexpectedly.","solutions":["Simply re-run the command and confirm a pick with Enter instead of Esc.","If the picker closes instantly, run inside a real TTY (not a piped/non-interactive shell) — the code already fails earlier with 'Human input required' when no terminal is available.","Check for stray ESC-producing terminal mappings if the picker aborts immediately."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Only enter interactive auth when a TTY is attached\nif !std::io::stdin().is_terminal() {\n    eprintln!(\"forge auth requires an interactive terminal\");\n    return Ok(());\n}","typeGuard":null,"tryCatchPattern":"match run_forge_auth(out).await {\n    Ok(()) => Ok(()),\n    Err(e) if e.to_string().contains(\"Could not determine which forge provider\") => {\n        Ok(()) // user cancelled the picker; treat as no-op, not a crash\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Treat picker cancellation as an expected outcome in wrappers and scripts.","Run forge auth only in a real terminal session.","Don't wrap the command in tools that swallow the TTY (piped `but` output)."],"tags":["interactive","picker","forge-auth","user-cancellation"],"backgroundTag":"prompt-cancelled","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}