BloopAI/vibe-kanban · critical

OS didn't give us a home directory

Error message

OS didn't give us a home directory

What it means

prod_asset_dir_path() calls directories::ProjectDirs::from("ai", "bloop", "vibe-kanban") and unwraps with expect("OS didn't give us a home directory"). ProjectDirs::from returns None when it cannot determine a home directory from the OS (e.g. $HOME unset and no passwd entry on Linux; missing profile env vars on Windows). The panic message is misleading — the problem is a missing home directory, not a bad OS.

Source

Thrown at crates/utils/src/assets.rs:26

        std::path::PathBuf::from(PROJECT_ROOT).join("../../dev_assets")
    } else {
        prod_asset_dir_path()
    };

    // Ensure the directory exists
    if !path.exists() {
        std::fs::create_dir_all(&path).expect("Failed to create asset directory");
    }

    path
    // ✔ macOS → ~/Library/Application Support/MyApp
    // ✔ Linux → ~/.local/share/myapp   (respects XDG_DATA_HOME)
    // ✔ Windows → %APPDATA%\Example\MyApp
}

pub fn prod_asset_dir_path() -> std::path::PathBuf {
    ProjectDirs::from("ai", "bloop", "vibe-kanban")
        .expect("OS didn't give us a home directory")
        .data_dir()
        .to_path_buf()
}

pub fn config_path() -> std::path::PathBuf {
    asset_dir().join("config.json")
}

pub fn profiles_path() -> std::path::PathBuf {
    asset_dir().join("profiles.json")
}

pub fn credentials_path() -> std::path::PathBuf {
    asset_dir().join("credentials.json")
}

pub fn trusted_keys_path() -> std::path::PathBuf {
    asset_dir().join("trusted_ed25519_public_keys.json")

View on GitHub (pinned to 4deb7eca8f)

Solutions

  1. Ensure $HOME is set to a writable directory in the environment (export HOME=/home/user or HOME=/tmp for CI).
  2. Set $XDG_DATA_HOME explicitly so the data dir can be resolved.
  3. When running as a service, set the HOME env var in the unit file/container spec (Environment=HOME=...).
  4. Refactor prod_asset_dir_path() to return Option/Result and fall back to std::env::temp_dir() or an explicit config value instead of panicking.

Example fix

// before
ProjectDirs::from("ai", "bloop", "vibe-kanban")
    .expect("OS didn't give us a home directory")
    .data_dir()
    .to_path_buf()
// after
ProjectDirs::from("ai", "bloop", "vibe-kanban")
    .map(|d| d.data_dir().to_path_buf())
    .unwrap_or_else(|| {
        std::env::var_os("XDG_DATA_HOME")
            .map(PathBuf::from)
            .unwrap_or_else(|| std::env::temp_dir().join("vibe-kanban"))
    })
Defensive patterns

Strategy: validation

Validate before calling

// run before any call that touches prod_asset_dir_path()/asset_dir()
fn ensure_home_resolvable() -> Result<(), String> {
    let has_home = std::env::var_os("HOME").map(|v| !v.is_empty()).unwrap_or(false);
    let has_xdg = std::env::var_os("XDG_DATA_HOME").is_some();
    if has_home || has_xdg {
        Ok(())
    } else {
        Err("HOME and XDG_DATA_HOME are unset; set HOME before running".into())
    }
}

Try / catch

let dir = std::panic::catch_unwind(prod_asset_dir_path)
    .unwrap_or_else(|_| std::env::temp_dir().join("vibe-kanban"));

Prevention

When it happens

Trigger: Calling prod_asset_dir_path() (directly or via asset_dir(), or read_execution_logs_for_execution which reaches it) on a system where directories::ProjectDirs::from returns None — typically $HOME is unset/empty on Linux or the equivalent base-dir env vars are missing.

Common situations: Running under systemd with a stripped environment, cron jobs without HOME, Docker containers running as non-root with no passwd entry, SSH with env_reset, headless CI runners with minimal env.

Related errors


AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29). Data as JSON: /api/errors/46caea47389bf3f0. Report an issue: GitHub.