{"record":{"id":"fc344095cf4d5cc2","repo":"ultraworkers/claw-code","slug":"home-is-not-set-on-windows-set-userprofile-or-ho","errorCode":null,"errorMessage":"HOME is not set (on Windows, set USERPROFILE or HOME, or use CLAW_CONFIG_HOME to point directly at the config directory)","messagePattern":"HOME is not set \\(on Windows, set USERPROFILE or HOME, or use CLAW_CONFIG_HOME to point directly at the config directory\\)","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"rust/crates/runtime/src/oauth.rs","lineNumber":340,"sourceCode":"        error: params.get(\"error\").cloned(),\n        error_description: params.get(\"error_description\").cloned(),\n    })\n}\n\nfn generate_random_token(bytes: usize) -> io::Result<String> {\n    let mut buffer = vec![0_u8; bytes];\n    File::open(\"/dev/urandom\")?.read_exact(&mut buffer)?;\n    Ok(base64url_encode(&buffer))\n}\n\nfn credentials_home_dir() -> io::Result<PathBuf> {\n    if let Some(path) = std::env::var_os(\"CLAW_CONFIG_HOME\") {\n        return Ok(PathBuf::from(path));\n    }\n    let home = std::env::var_os(\"HOME\")\n        .or_else(|| std::env::var_os(\"USERPROFILE\"))\n        .ok_or_else(|| {\n            io::Error::new(\n                io::ErrorKind::NotFound,\n                \"HOME is not set (on Windows, set USERPROFILE or HOME, \\\n                 or use CLAW_CONFIG_HOME to point directly at the config directory)\",\n            )\n        })?;\n    Ok(PathBuf::from(home).join(\".claw\"))\n}\n\nfn read_credentials_root(path: &PathBuf) -> io::Result<Map<String, Value>> {\n    match fs::read_to_string(path) {\n        Ok(contents) => {\n            if contents.trim().is_empty() {\n                return Ok(Map::new());\n            }\n            serde_json::from_str::<Value>(&contents)\n                .map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?\n                .as_object()\n                .cloned()","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/ultraworkers/claw-code/blob/08106b0c3771ef5b4a5aa176acccd460e88b7325/rust/crates/runtime/src/oauth.rs#L322-L358","documentation":"Thrown by credentials_home_dir() in the OAuth credentials layer when neither CLAW_CONFIG_HOME nor HOME nor USERPROFILE is set in the process environment. The runtime needs a directory to place ~/.claw/credentials.json for OAuth tokens, and without any home indicator it cannot construct that path. It surfaces as io::Error with ErrorKind::NotFound, so it can masquerade as a file-not-found error if you only match on kind.","triggerScenarios":"Any call that resolves the credentials path, e.g. the load/save helpers at oauth.rs:266-296 that call credentials_home_dir()?.join(\"credentials.json\") — typically triggered by starting an OAuth login flow or refreshing stored tokens. Occurs when the process is spawned with a scrubbed environment (env -i, minimal Docker containers, systemd units without EnvironmentFile, cron or CI runners that drop HOME).","commonSituations":"Running the claw binary in Docker/scratch containers that never set HOME; Windows services or scheduled tasks where USERPROFILE is not inherited; su/sudo invocations that reset environment variables; CI pipelines using env -u HOME; test harnesses that clear the environment between cases.","solutions":["Set CLAW_CONFIG_HOME to an explicit config directory (this takes priority and bypasses home-dir lookup entirely): export CLAW_CONFIG_HOME=/path/to/config","Set HOME on Unix: export HOME=/home/user — or USERPROFILE on Windows: set USERPROFILE=C:\\Users\\user","If spawning claw from code, pass the env var explicitly: std::process::Command::new(\"claw\").env(\"HOME\", home_dir)","For Docker, add ENV HOME=/root or ENV CLAW_CONFIG_HOME=/claw-config to the image","In tests, set CLAW_CONFIG_HOME to a tempfile::tempdir() path instead of mutating HOME (matches the repo's dogfooding convention)"],"exampleFix":"// before (fails in container: no HOME, no USERPROFILE)\ndocker run --rm claw-image claw login\n\n# after\nexport CLAW_CONFIG_HOME=/tmp/claw-config   # or set HOME=/root in the image\nclaw login","handlingStrategy":"validation","validationCode":"fn ensure_config_home() -> Result<(), std::io::Error> {\n    if std::env::var_os(\"CLAW_CONFIG_HOME\").is_some() { return Ok(()); }\n    let home = std::env::var_os(\"HOME\")\n        .or_else(|| std::env::var_os(\"USERPROFILE\"));\n    home.map(|_| ()).ok_or_else(|| std::io::Error::new(\n        std::io::ErrorKind::NotFound,\n        \"set CLAW_CONFIG_HOME, HOME, or USERPROFILE before OAuth operations\",\n    ))\n}\n\n// before any oauth call:\nensure_config_home()?;","typeGuard":null,"tryCatchPattern":"match runtime::oauth::load_credentials() {\n    Ok(creds) => { /* ... */ }\n    Err(e) if e.kind() == std::io::ErrorKind::NotFound\n        && e.to_string().contains(\"HOME is not set\") => {\n        eprintln!(\"no home directory: set CLAW_CONFIG_HOME or HOME\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always set CLAW_CONFIG_HOME in containers, systemd units, cron jobs, and tests — it is the deterministic override with no OS-dependent semantics","When spawning claw from other processes, inherit or explicitly set HOME/USERPROFILE rather than passing a scrubbed env","In CI, export CLAW_CONFIG_HOME=$(mktemp -d) to isolate tests from the runner's home state"],"tags":["oauth","credentials","environment","home-dir","rust"],"backgroundTag":"missing-env-var","analyzedSha":"08106b0c3771ef5b4a5aa176acccd460e88b7325","analyzedAt":"2026-08-18T00:29:38.590Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}