gitbutlerapp/gitbutler · error

askpass broker must be initialized

Error message

askpass broker must be initialized

What it means

submit_prompt_response() delivers a user's answer to a pending credential prompt through the process-global askpass broker. get_broker() yields Some only when the host called but_askpass::try_init()/init() at startup (GUI mode); it yields None when the broker was explicitly disabled (CLI mode). Submitting a response with no active broker is rejected.

Source

Thrown at crates/but-api/src/legacy/askpass.rs:15

//! In place of commands.rs
use anyhow::anyhow;
use but_askpass::{self as askpass, AskpassRequestId};
use serde::Deserialize;

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SubmitPromptResponseParams {
    pub id: AskpassRequestId,
    pub response: Option<String>,
}

pub async fn submit_prompt_response(params: SubmitPromptResponseParams) -> anyhow::Result<()> {
    askpass::get_broker()
        .ok_or(anyhow!("askpass broker must be initialized"))?
        .handle_response(params.id, params.response)
        .await;
    Ok(())
}

View on GitHub (pinned to 2497b8007a)

Solutions

  1. Call but_askpass::try_init(submit_prompt_callback) exactly once during host startup, before any fetch/push that can prompt
  2. Do not route submitPromptResponse to a host that disabled the broker; treat it as a no-op in CLI hosts
  3. In tests, initialize (or explicitly disable and assert on) the broker before invoking the command

Example fix

// before: host never configures askpass; later submit_prompt_response fails
// with 'askpass broker must be initialized'

// after: configure once at startup
but_askpass::try_init(move |prompt| {
    forward_prompt_to_ui(prompt); // GUI callback
}).expect("broker configured once at startup");
Defensive patterns

Strategy: validation

Validate before calling

match but_askpass::try_get_broker() {
    Some(Some(_)) => { /* broker active: safe to submit */ }
    Some(None) => { /* broker disabled (CLI): ignore the submission */ }
    None => { /* host bug: call but_askpass::try_init() at startup */ }
}

Type guard

fn askpass_ready() -> bool {
    matches!(but_askpass::try_get_broker(), Some(Some(_)))
}

Try / catch

if let Err(err) = submit_prompt_response(params).await {
    if err.to_string().contains("askpass broker must be initialized") {
        // drop the stale prompt UI; re-auth will raise a fresh prompt
    }
}

Prevention

When it happens

Trigger: Invoking the submitPromptResponse command in a host that ran but_askpass::disable() (CLI configuration) or never initialized the broker before the first credential-needing operation; a delayed frontend response arriving in a host that does not own the broker.

Common situations: Embedding but-api in a custom host without the startup init sequence; tests invoking the command directly; CLI and GUI processes sharing a frontend event stream.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17). Data as JSON: /api/errors/5321adec2adfd069. Report an issue: GitHub.