gitbutlerapp/gitbutler · warning · anyhow::Error

Could not determine which forge provider to authenticate wit

Error message

Could not determine which forge provider to authenticate with

What it means

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.

Source

Thrown at crates/but/src/command/config.rs:900

    }

    let auth_options = nonempty::nonempty![
        ("GitHub", ForgeProvider::GitHub),
        ("GitLab", ForgeProvider::GitLab),
        ("Bitbucket", ForgeProvider::Bitbucket)
    ];
    let selected_option = {
        let mut input = out
            .prepare_for_terminal_input()
            .context("Human input required - run this in a terminal")?;
        input
            .prompt_select(
                "Select a forge provider to authenticate with",
                &auth_options,
            )?
            .cloned()
            .ok_or_else(|| {
                anyhow::anyhow!("Could not determine which forge provider to authenticate with")
            })?
    };

    match selected_option {
        ForgeProvider::GitHub => github_auth(out).await,
        ForgeProvider::GitLab => gitlab_auth(out).await,
        ForgeProvider::Bitbucket => bitbucket_auth(out).await,
    }
}

/// Authenticate with Bitbucket Cloud using an Atlassian API token.
async fn bitbucket_auth(out: &mut OutputChannel) -> Result<()> {
    use but_bitbucket::AuthStatusResponse;

    let t = theme::get();
    let mut inout = out
        .prepare_for_terminal_input()
        .context("Human input required - run this in a terminal")?;

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Simply re-run the command and confirm a pick with Enter instead of Esc.
  2. 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.
  3. Check for stray ESC-producing terminal mappings if the picker aborts immediately.
Defensive patterns

Strategy: try-catch

Validate before calling

// Only enter interactive auth when a TTY is attached
if !std::io::stdin().is_terminal() {
    eprintln!("forge auth requires an interactive terminal");
    return Ok(());
}

Try / catch

match run_forge_auth(out).await {
    Ok(()) => Ok(()),
    Err(e) if e.to_string().contains("Could not determine which forge provider") => {
        Ok(()) // user cancelled the picker; treat as no-op, not a crash
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: 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.

Common situations: Users exploring `but config` menus and backing out with Esc; SSH sessions dropped mid-prompt; terminal emulators sending an escape keypress unexpectedly.

Understand the failure class

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/8f44ff218419e90a. Report an issue: GitHub.