gitbutlerapp/gitbutler · error
askpass broker must be initialized
Error message
askpass broker must be initialized
What it means
handle_git_prompt_push is the askpass hook for pushes: when git asks for credentials and the executor carried a push context (Some(branch_id)), it calls but_askpass::get_broker(). That global returns Some only after but_askpass::init() ran (GUI startup, gitbutler-tauri/src/main.rs:146); after but_askpass::disable() (the CLI path) it returns None and expect("askpass broker must be initialized") panics. If neither init nor disable ever ran, get_broker() itself panics with 'broker has not been configured' first.
Source
Thrown at crates/gitbutler-git/src/context.rs:346
.to_owned();
Ok((remote, short_name))
}
fn now_ms() -> u128 {
UNIX_EPOCH
.elapsed()
.expect("system time is set before the Unix epoch")
.as_millis()
}
async fn handle_git_prompt_push(
prompt: String,
askpass: Option<Option<StackId>>,
) -> Option<String> {
if let Some(branch_id) = askpass {
tracing::info!("received prompt for branch push {branch_id:?}: {prompt:?}");
askpass::get_broker()
.expect("askpass broker must be initialized")
.submit_prompt(prompt, askpass::Context::Push { branch_id })
.await
} else {
tracing::warn!("received askpass push prompt but no broker was supplied; returning None");
None
}
}
async fn handle_git_prompt_fetch(prompt: String, askpass: Option<String>) -> Option<String> {
if let Some(action) = askpass {
tracing::info!("received prompt for fetch with action {action:?}: {prompt:?}");
askpass::get_broker()
.expect("askpass broker must be initialized")
.submit_prompt(prompt, askpass::Context::Fetch { action })
.await
} else {
tracing::warn!("received askpass fetch prompt but no broker was supplied; returning None");
NoneView on GitHub (pinned to caf1f223d3)
Solutions
- Call but_askpass::init(prompt_handler) exactly once at startup before any push/fetch, as the Tauri app does
- For non-GUI hosts, pass askpass: None when invoking push so the handler logs a warning and returns None instead of panicking
- Pre-check the broker state with the public but_askpass::try_get_broker() before supplying askpass contexts (see exampleFix)
Example fix
// before
but_askpass::disable();
push_with_askpass_context(Some(stack_id)).await; // panics: 'askpass broker must be initialized'
// after
if but_askpass::try_get_broker() == Some(None) {
// broker explicitly disabled (CLI mode): don't attach askpass contexts
push_with_askpass_context(None).await;
} else {
but_askpass::init(handler);
push_with_askpass_context(Some(stack_id)).await;
} Defensive patterns
Strategy: validation
Validate before calling
// Pre-check the global broker state before attaching push askpass contexts
match but_askpass::try_get_broker() {
Some(Some(_)) => { /* broker active: push with Some(stack_id) context */ }
Some(None) => { /* disabled (CLI): pass askpass: None */ }
None => { /* never initialized: call but_askpass::init(handler) first */ }
} Type guard
fn askpass_broker_active() -> bool {
but_askpass::try_get_broker() == Some(Some(/* broker placeholder */))
// practically: matches!(but_askpass::try_get_broker(), Some(Some(_)))
} Prevention
- Call but_askpass::init() exactly once at GUI startup, before the first push (see gitbutler-tauri/src/main.rs:146)
- In CLI/embedded hosts, call but_askpass::disable() AND construct push calls with askpass: None
- Use the public try_get_broker() to assert the expected mode in test setups instead of assuming
When it happens
Trigger: A push that triggers a credential prompt in a process that wired the askpass push context but called but_askpass::disable() - or an embedded host/test that constructs the GixExecutor with askpass Some(..) and never calls but_askpass::init().
Common situations: Embedding gitbutler-git in another app or N-API host, test harnesses exercising push with askpass contexts, or startup-order regressions where disable() wins over GUI initialization.
Related errors
- broker has not been configured
- broker already configured
- unused
- Branch `{}` is pushed, but its remote ancestry does not matc
- repo access failed
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/302bb4e84ca1f1ac.
Report an issue: GitHub.