Hmbown/CodeWhale · error · anyhow

Home directory unavailable

Error message

Home directory unavailable

What it means

Thrown when constructing the MCP external-import collector: `crate::config::effective_home_dir()` returned None, so no home directory could be resolved. The import feature needs the home dir to discover external MCP client configs (e.g. other tools' config files), and without it discovery cannot run.

Solutions

  1. Set the HOME environment variable before launching codewhale (e.g. `Environment=HOME=/home/user` in a systemd unit or `export HOME=$(getent passwd $USER | cut -d: -f6)`).
  2. Run under a login shell (`su -l user -c ...` or `ssh user@host`) so HOME is populated.
  3. If running in a container, add `ENV HOME=/root` or run with `docker run -e HOME=...`.

Example fix

// before (Dockerfile)
CMD ["codewhale"]
// after
ENV HOME=/home/appuser
CMD ["codewhale"]
Defensive patterns

Strategy: fallback

Validate before calling

let has_home = std::env::var_os("HOME").map(|h| !h.is_empty()).unwrap_or(false);
if !has_home { eprintln!("HOME must be set before running codewhale"); }

Type guard

fn has_home_dir() -> bool { crate::config::effective_home_dir().is_some() }

Try / catch

match ImportContext::new(...) {
    Err(e) if e.to_string().contains("Home directory unavailable") => {
        // fall back to an explicit home or surface a setup hint
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling `ImportContext::new` (or the constructor wrapping `Self { ... }`) on a system where $HOME is unset and no passwd-derived home could be determined — e.g. a stripped CI container, an systemd/timer service with a minimal environment, or running the binary via a login shell replacement that clears the environment.

Common situations: Docker containers running as a non-root user without HOME set; cron/systemd units lacking `Environment=HOME=...`; SSH exec commands without `-l` that skip loading the environment.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/1eb59e517d083bb0. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/mcp/external_import.rs:509

pub struct ImportContext<'a> {
    pub workspace: &'a Path,
    pub mcp_path: &'a Path,
    pub plugins: &'a crate::plugins::PluginRegistry,
    pub home: PathBuf,
    pub codewhale_home: PathBuf,
}
impl<'a> ImportContext<'a> {
    pub fn new(
        workspace: &'a Path,
        mcp_path: &'a Path,
        plugins: &'a crate::plugins::PluginRegistry,
    ) -> anyhow::Result<Self> {
        Ok(Self {
            workspace,
            mcp_path,
            plugins,
            home: crate::config::effective_home_dir()
                .ok_or_else(|| anyhow::anyhow!("Home directory unavailable"))?,
            codewhale_home: codewhale_config::codewhale_home()?,
        })
    }
    fn discover(&self) -> (Vec<ImportCandidate>, Vec<ImportProblem>) {
        let sources = [
            (
                self.home.join(".claude.json"),
                ExternalMcpSourceKind::ClaudeJson,
            ),
            (
                self.workspace.join(".mcp.json"),
                ExternalMcpSourceKind::ProjectMcpJson,
            ),
            (
                self.codewhale_home.join("mcp-marketplace.json"),
                ExternalMcpSourceKind::Marketplace,
            ),
        ];

View on GitHub (pinned to 73e0f67d83)