gitbutlerapp/gitbutler · error
broker has not been configured
Error message
broker has not been configured
What it means
`get_broker()` (lib.rs:83) panics when the global `OnceLock<Option<AskpassBroker>>` was never set by `init()`, `try_init()`, or `disable()`. The panic is intentional: the broker's state decides whether GitButler's askpass overrides are used, and an unset broker would let credential prompts silently leak to the terminal that started the GUI. `try_get_broker()` returns `Option<Option<AskpassBroker>>` and is the non-panicking probe.
Source
Thrown at crates/but-askpass/src/lib.rs:83
/// This function should be called **exactly once** during startup if the custom askpass broker
/// should **not** be used (currently the sensible approach for CLI). Otherwise, call [`init`] at
/// startup instead.
pub fn disable() {
GLOBAL_ASKPASS_BROKER
.set(None)
.unwrap_or_else(|_| panic!("broker already configured"))
}
/// Get the global askpass broker, assuming it's configured.
///
/// # Panics
/// Panics if neither [`init`] nor [`disable`] has been called. This is an important property as we
/// use the state of the broker to determine whether to use our askpass overrides or not. If it's
/// not explicitly set, there is no way to tell the intent and bugs may hide in unexpected places
/// as a consequence. For example, if not initialized for the GUI, the prompt may show up in the
/// terminal that started the GUI.
pub fn get_broker() -> Option<AskpassBroker> {
try_get_broker().unwrap_or_else(|| panic!("broker has not been configured"))
}
/// Fallibly get the global askpass broker state.
///
/// Returns `None` if neither [`init`], [`try_init`], nor [`disable`] has configured the broker.
pub fn try_get_broker() -> Option<Option<AskpassBroker>> {
GLOBAL_ASKPASS_BROKER.get().cloned()
}
struct AskpassRequest {
sender: oneshot::Sender<Option<String>>,
}
/// An ID for an askpass request.
pub type AskpassRequestId = but_core::Id<'A'>;
/// Additional context sent alongside a credential prompt.
#[derive(Debug, Clone, Serialize)]View on GitHub (pinned to caf1f223d3)
Solutions
- Call `disable()` once at CLI startup, or `init()`/`try_init()` for GUI functionality, before any git network operation.
- Switch probing code to `try_get_broker()`, which distinguishes 'not configured' from 'configured as disabled'.
- If hit in tests, add the startup call to the test harness setup.
Example fix
// before
let broker = but_askpass::get_broker(); // panics if never configured
// after
match but_askpass::try_get_broker() {
Some(broker) => { /* configured (or None = disabled) */ }
None => { /* run startup init()/disable() first */ }
} Defensive patterns
Strategy: validation
Validate before calling
match but_askpass::try_get_broker() {
Some(_) => {
// init() or disable() already ran; get_broker() is safe
let _broker = but_askpass::get_broker();
}
None => {
// not configured yet: run init()/disable() before any git network operation
but_askpass::disable();
}
} Type guard
fn broker_ready() -> bool {
// Some(_) means init() or disable() ran; None means get_broker() would panic
but_askpass::try_get_broker().is_some()
} Try / catch
let broker = std::panic::catch_unwind(std::panic::AssertUnwindSafe(but_askpass::get_broker))
.unwrap_or_else(|_| panic!("askpass broker used before init()/disable() — add startup setup")); Prevention
- Make broker setup the first GitButler call in main()/entrypoint, before spawning threads that do git I/O.
- Use try_get_broker() in defensive or test code instead of get_broker().
- grep new binaries/tests for get_broker() and confirm each has a preceding setup call.
When it happens
Trigger: Calling `but_askpass::get_broker()` in a binary that never ran `init()`/`try_init()`/`disable()` at startup; linking but-askpass into a new test binary or N-API host without the one-time setup call; code that runs before main-level initialization.
Common situations: New host application wired to the but-* crates with missing startup boilerplate; unit tests exercising askpass paths without the global setup; race where a background thread calls `get_broker()` before startup completes.
Related errors
- askpass broker must be initialized
- broker already configured
- unused
- theme::init() must be called before getting the theme
- tauri event emission doesn't fail in practice
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/7196d3d5cd0d0235.
Report an issue: GitHub.