From b95d330310011f7c018deba7db455b1c8308e6d2 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 10 Apr 2026 08:33:35 +0900 Subject: [PATCH] fix(startup): fall back to USERPROFILE when HOME is not set (Windows) On Windows, HOME is often unset. The CLI crashed at startup with 'error: io error: HOME is not set' because three paths only checked HOME: - config_home_dir() in tools crate (config/settings loading) - credentials_home_dir() in runtime crate (OAuth credentials) - detect_broad_cwd() in CLI (CWD-is-home-dir check) - skill lookup roots in tools crate All now fall through to USERPROFILE when HOME is absent. Error message updated to suggest USERPROFILE or CLAW_CONFIG_HOME on Windows. Source: MaxDerVerpeilte in #claw-code (Windows user, 2026-04-10). --- rust/crates/runtime/src/oauth.rs | 9 ++++++++- rust/crates/rusty-claude-cli/src/main.rs | 1 + rust/crates/tools/src/lib.rs | 11 +++++++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/rust/crates/runtime/src/oauth.rs b/rust/crates/runtime/src/oauth.rs index 4d2150c..aa3ca15 100644 --- a/rust/crates/runtime/src/oauth.rs +++ b/rust/crates/runtime/src/oauth.rs @@ -335,7 +335,14 @@ fn credentials_home_dir() -> io::Result { return Ok(PathBuf::from(path)); } let home = std::env::var_os("HOME") - .ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "HOME is not set"))?; + .or_else(|| std::env::var_os("USERPROFILE")) + .ok_or_else(|| { + io::Error::new( + io::ErrorKind::NotFound, + "HOME is not set (on Windows, set USERPROFILE or HOME, \ + or use CLAW_CONFIG_HOME to point directly at the config directory)", + ) + })?; Ok(PathBuf::from(home).join(".claw")) } diff --git a/rust/crates/rusty-claude-cli/src/main.rs b/rust/crates/rusty-claude-cli/src/main.rs index 8c4469b..95c2cc6 100644 --- a/rust/crates/rusty-claude-cli/src/main.rs +++ b/rust/crates/rusty-claude-cli/src/main.rs @@ -3055,6 +3055,7 @@ fn detect_broad_cwd() -> Option { return None; }; let is_home = env::var_os("HOME") + .or_else(|| env::var_os("USERPROFILE")) .map(|h| PathBuf::from(h) == cwd) .unwrap_or(false); let is_root = cwd.parent().is_none(); diff --git a/rust/crates/tools/src/lib.rs b/rust/crates/tools/src/lib.rs index 84eadc0..de3c758 100644 --- a/rust/crates/tools/src/lib.rs +++ b/rust/crates/tools/src/lib.rs @@ -3066,7 +3066,7 @@ fn skill_lookup_roots() -> Vec { if let Ok(codex_home) = std::env::var("CODEX_HOME") { push_prefixed_skill_lookup_roots(&mut roots, std::path::Path::new(&codex_home)); } - if let Ok(home) = std::env::var("HOME") { + if let Ok(home) = std::env::var("HOME").or_else(|_| std::env::var("USERPROFILE")) { push_home_skill_lookup_roots(&mut roots, std::path::Path::new(&home)); } if let Ok(claude_config_dir) = std::env::var("CLAUDE_CONFIG_DIR") { @@ -4987,7 +4987,14 @@ fn config_home_dir() -> Result { if let Ok(path) = std::env::var("CLAW_CONFIG_HOME") { return Ok(PathBuf::from(path)); } - let home = std::env::var("HOME").map_err(|_| String::from("HOME is not set"))?; + let home = std::env::var("HOME") + .or_else(|_| std::env::var("USERPROFILE")) + .map_err(|_| { + String::from( + "HOME is not set (on Windows, set USERPROFILE or HOME, \ + or use CLAW_CONFIG_HOME to point directly at the config directory)", + ) + })?; Ok(PathBuf::from(home).join(".claw")) }