gitbutlerapp/gitbutler · critical
missing config dir
Error message
missing config dir
What it means
gitbutler-tauri's main() resolves the settings directory with but_path::app_config_dir().expect("missing config dir"). app_config_dir() wraps dirs::config_dir(), which returns None when the platform's config location cannot be determined: on Linux when $HOME is unset/empty or $XDG_CONFIG_HOME is set to a relative path, on macOS when no home directory exists, on Windows when the known-folder lookup fails. The expect converts that environment problem into an immediate startup panic; setting E2E_TEST_APP_DATA_DIR bypasses dirs::config_dir() entirely (but-path/src/lib.rs:93-100).
Source
Thrown at crates/gitbutler-tauri/src/main.rs:53
but_askpass::disable();
return runtime.block_on(but::handle_args(std::env::args_os()));
}
}
let performance_logging = std::env::var_os("GITBUTLER_PERFORMANCE_LOG").is_some();
let tauri_debug_logging = std::env::var_os("GITBUTLER_TAURI_DEBUG_LOG").is_some();
let mut tauri_context = generate_context!();
but_secret::secret::set_application_namespace(&tauri_context.config().identifier);
// Set the macOS notification bundle ID so notifications appear as GitButler.
#[cfg(target_os = "macos")]
{
if let Err(e) = notify_rust::set_application(&tauri_context.config().identifier) {
tracing::warn!(error = %e, "Failed to set notification application");
}
}
let config_dir = but_path::app_config_dir().expect("missing config dir");
std::fs::create_dir_all(&config_dir).expect("failed to create config dir");
let custom_settings = cfg!(feature = "packaged-but-distribution")
.then(but_settings::customization::packaged_but_binary);
// While it serves a function, this behavior is sub-optimal. The proper solution is to decouple:
// - Checking for updates from
// - Performing an update
// This way people can be informed that there is an update even if self-updating is not possible (i.e. installed via package manager).
let custom_settings = if cfg!(feature = "disable-auto-updates") {
but_settings::customization::merge_two(
but_settings::customization::disable_auto_update_checks(),
custom_settings,
)
.into()
} else {
custom_settings
};
let mut app_settings =
AppSettingsWithDiskSync::new_with_customization(config_dir.clone(), custom_settings)View on GitHub (pinned to caf1f223d3)
Solutions
- Launch the app with a valid HOME (export HOME=/home/<user>)
- Make XDG_CONFIG_HOME an absolute path or unset it so the default ~/.config is used
- For automated runs, set E2E_TEST_APP_DATA_DIR to a writable directory - it overrides the lookup
- As a contributor: replace the expect with ? so main() reports the failure cleanly (see exampleFix)
Example fix
// before
let config_dir = but_path::app_config_dir().expect("missing config dir");
// after
let config_dir = but_path::app_config_dir()
.context("could not resolve config dir (is $HOME set and absolute?)")?; Defensive patterns
Strategy: validation
Validate before calling
// Environment pre-check mirroring dirs::config_dir() requirements
fn config_dir_resolvable() -> bool {
if std::env::var_os("E2E_TEST_APP_DATA_DIR").is_some() {
return true;
}
#[cfg(target_os = "linux")]
{
let home_ok = std::env::var_os("HOME").is_some_and(|h| !h.is_empty());
let xdg_ok = std::env::var_os("XDG_CONFIG_HOME")
.map(|v| std::path::Path::new(&v).is_absolute())
.unwrap_or(true);
home_ok && xdg_ok
}
#[cfg(not(target_os = "linux"))]
{ true }
} Prevention
- Launch desktop apps from full user sessions; services need HOME (or E2E_TEST_APP_DATA_DIR) set explicitly
- Keep XDG_CONFIG_HOME absolute or unset
- Prefer propagating the Result from but_path::app_config_dir() instead of expect in entry points
When it happens
Trigger: Launching the desktop app from an environment without a resolvable config directory: HOME unset or empty (services, daemons, minimal containers, some CI runners), a relative XDG_CONFIG_HOME on Linux, or a broken user profile.
Common situations: Running the app from systemd/launchd/cron without a full user environment, inside minimal Docker images, after HOME was cleared, or with misconfigured XDG variables.
Related errors
- Could not get app data dir
- failed to create logs dir
- initializing rolling file appender failed
- product name not set
- failed to create config dir
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/a79b122d21fb53f5.
Report an issue: GitHub.