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
- 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)`).
- Run under a login shell (`su -l user -c ...` or `ssh user@host`) so HOME is populated.
- 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
- Always launch the binary with HOME set in service/container definitions
- Add HOME to smoke-test environments
- Prefer login shells for remote execution
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
- Cannot resolve the user-global model configuration.
- CF_ACCOUNT_ID and CF_API_TOKEN are required
- Codewhale home directory not found
- CODEWHALE_HOME / user home is unavailable
- Failed to resolve settings path: no config directory found.
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)