gitbutlerapp/gitbutler · critical

failed to create app settings

Error message

failed to create app settings

What it means

Startup panic in but-server: AppSettingsWithDiskSync::new_with_customization could not load or create the app settings under the configured config directory. Because this is an expect on server boot, any underlying failure - a corrupt settings file, an unwritable or missing config dir, a path occupied by a file, or a full disk - aborts the whole process before it serves anything.

Source

Thrown at crates/but-server/src/lib.rs:381

            is_localhost_origin(origin.as_bytes())
        }))
        .allow_headers(allowed_headers)
        .allow_credentials(true);

    let config_dir = but_path::app_config_dir().unwrap();
    let app_data_dir = but_path::app_data_dir().unwrap();

    let broadcaster = Arc::new(Mutex::new(Broadcaster::new()));
    let archival = Arc::new(but_feedback::Archival {
        cache_dir: app_data_dir.join("cache").clone(),
        logs_dir: app_data_dir.join("logs").clone(),
    });
    let extra = Extra {
        active_projects: Arc::new(Mutex::new(ActiveProjects::new())),
        archival,
    };
    let app_settings = AppSettingsWithDiskSync::new_with_customization(config_dir.clone(), None)
        .expect("failed to create app settings");

    // If a project path was provided, auto-activate that project.
    if let Some(ref project_path) = config.project_path {
        match but_ctx::Context::discover(project_path) {
            Ok(mut ctx) => {
                but_api::legacy::projects::prepare_project_for_activation(&mut ctx).ok();
                let mut active = extra.active_projects.lock().await;
                if active
                    .set_active(&ctx, &broadcaster, app_settings.clone())
                    .is_err()
                {
                    tracing::warn!("Failed to activate project at {}", project_path.display());
                }
            }
            Err(err) => {
                tracing::warn!(
                    "Could not discover project at {}: {err}",
                    project_path.display()

View on GitHub (pinned to 2497b8007a)

Solutions

  1. Make sure the config directory exists and is writable by the running user
  2. Move aside or delete the existing settings file so a fresh one can be created
  3. Free disk space if writes fail with ENOSPC
  4. Re-run the binary and read the stderr just above the panic for the underlying io/parse error

Example fix

// before
let app_settings = AppSettingsWithDiskSync::new_with_customization(config_dir.clone(), None)
    .expect("failed to create app settings");

// after
let app_settings = AppSettingsWithDiskSync::new_with_customization(config_dir.clone(), None)
    .map_err(|e| anyhow::anyhow!("app settings in {}: {e}", config_dir.display()))?;
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight before server boot: the config dir must be writable
let probe = config_dir.join(".write-probe");
std::fs::write(&probe, b"").with_context(|| format!("config dir {} not writable", config_dir.display()))?;
std::fs::remove_file(&probe).ok();

Prevention

When it happens

Trigger: Starting the server with a config dir mounted read-only (container volume) or owned by another user; settings JSON corrupted by a partial write or manual edit; config_dir pointing at a regular file; ENOSPC when persisting the initial defaults.

Common situations: Docker/Kubernetes deployments with mismatched volume mounts; a previous crash interrupting a settings write; running as a service user without ownership of the config directory.

Related errors


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