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

cache_dir() panics when directories::ProjectDirs::from returns None in the debug_assertions branch (qualifier "ai", organization "bloop-dev"). This happens when the OS cannot supply a home/base directory, so the Option is None and expect("OS didn't give us a home directory") fires. The qualifier difference is irrelevant to the failure — only the missing home directory matters.

Source

Thrown at crates/utils/src/lib.rs:54

        }

        // Check /proc/version for WSL2 signature
        if let Ok(version) = std::fs::read_to_string("/proc/version")
            && (version.contains("WSL2") || version.contains("microsoft"))
        {
            tracing::debug!("WSL2 detected via /proc/version");
            return true;
        }

        tracing::debug!("WSL2 not detected");
        false
    })
}

pub fn cache_dir() -> std::path::PathBuf {
    let proj = if cfg!(debug_assertions) {
        ProjectDirs::from("ai", "bloop-dev", env!("CARGO_PKG_NAME"))
            .expect("OS didn't give us a home directory")
    } else {
        ProjectDirs::from("ai", "bloop", env!("CARGO_PKG_NAME"))
            .expect("OS didn't give us a home directory")
    };

    // ✔ macOS → ~/Library/Caches/MyApp
    // ✔ Linux → ~/.cache/myapp (respects XDG_CACHE_HOME)
    // ✔ Windows → %LOCALAPPDATA%\Example\MyApp
    proj.cache_dir().to_path_buf()
}

// Get or create cached PowerShell script file
pub async fn get_powershell_script()
-> Result<std::path::PathBuf, Box<dyn std::error::Error + Send + Sync>> {
    use std::io::Write;

    let cache_dir = cache_dir();
    let script_path = cache_dir.join("toast-notification.ps1");

View on GitHub (pinned to 4deb7eca8f)

Solutions

  1. Set $HOME in your shell/service environment before running a debug build.
  2. Set $XDG_CACHE_HOME as an explicit override.
  3. If running as a container user not in /etc/passwd, add the user or set HOME manually.
  4. Refactor cache_dir() to return Result and fall back to std::env::temp_dir().join(env!("CARGO_PKG_NAME")) when ProjectDirs is None.

Example fix

// before
let proj = if cfg!(debug_assertions) {
    ProjectDirs::from("ai", "bloop-dev", env!("CARGO_PKG_NAME"))
        .expect("OS didn't give us a home directory")
} else {
    ProjectDirs::from("ai", "bloop", env!("CARGO_PKG_NAME"))
        .expect("OS didn't give us a home directory")
};
// after
let proj = ProjectDirs::from("ai", "bloop-dev", env!("CARGO_PKG_NAME"))
    .with_context(|| "cannot resolve home directory: is $HOME set?")?;
Defensive patterns

Strategy: validation

Validate before calling

// before calling cache_dir() in a debug build
if std::env::var_os("HOME").map(|v| v.is_empty()).unwrap_or(true)
    && std::env::var_os("XDG_CACHE_HOME").is_none()
{
    eprintln!("HOME/XDG_CACHE_HOME unset: cache_dir() will panic; set them first");
}

Try / catch

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

Prevention

When it happens

Trigger: Calling cache_dir() (or get_powershell_script, which calls cache_dir) in a debug build where ProjectDirs::from("ai", "bloop-dev", ...) returns None — $HOME unset/empty on Linux or missing profile/appdata env vars on Windows.

Common situations: Local dev under a stripped environment: `env -i cargo run`, cron/systemd timers without HOME, Docker dev containers with a non-existent user (no passwd entry), CI runners with minimal env.

Related errors


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