{"record":{"id":"28dd703686e4e6be","repo":"Hmbown/CodeWhale","slug":"codewhale-home-user-home-is-unavailable","errorCode":null,"errorMessage":"CODEWHALE_HOME / user home is unavailable","messagePattern":"CODEWHALE_HOME / user home is unavailable","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/cloud_dispatch.rs","lineNumber":281,"sourceCode":"            ),\n        }\n    }\n}\n\nimpl std::error::Error for DispatchError {}\n\n/// File-backed store under `$CODEWHALE_HOME/cloud-jobs`.\n#[derive(Debug, Clone)]\npub struct CloudJobStore {\n    root: PathBuf,\n}\n\nimpl CloudJobStore {\n    /// Resolve the process Codewhale home.\n    pub fn from_env() -> Result<Self> {\n        let home = codewhale_home()\n            .map_err(|err| anyhow!(err.to_string()))?\n            .ok_or_else(|| anyhow!(\"CODEWHALE_HOME / user home is unavailable\"))?;\n        Ok(Self::from_path(home.join(\"cloud-jobs\")))\n    }\n\n    /// Test and injected-root constructor.\n    pub fn from_path(root: PathBuf) -> Self {\n        Self { root }\n    }\n\n    /// Persist a job atomically. Never writes credentials.\n    pub fn save(&self, job: &CloudJob) -> Result<()> {\n        fs::create_dir_all(&self.root).context(\"failed to create cloud-jobs directory\")?;\n        let path = self.job_path(&job.id)?;\n        let tmp = path.with_extension(\"json.tmp\");\n        let body = serde_json::to_vec_pretty(job).context(\"failed to encode cloud job\")?;\n        {\n            let mut file =\n                fs::File::create(&tmp).context(\"failed to start a private cloud job write\")?;\n            file.write_all(&body)","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/cloud_dispatch.rs#L263-L299","documentation":"CloudJobStore::from_env could not resolve the Codewhale home directory: `codewhale_home()` returned Ok(None), meaning neither CODEWHALE_HOME nor the user's home directory could be determined. Cloud job state cannot be stored, so construction fails.","triggerScenarios":"Calling CloudJobStore::from_env (crates/tui/src/cloud_dispatch.rs:281) in an environment where CODEWHALE_HOME is unset AND the user home directory cannot be resolved (e.g. no HOME/XDG on Unix, or failing `home_dir()` lookup).","commonSituations":"Running the TUI in a stripped container/systemd service without HOME set, CI jobs running as a user without a home directory, or a malformed CODEWHALE_HOME scenario being bypassed to the None branch.","solutions":["Set CODEWHALE_HOME to a writable directory","Ensure HOME (or the platform user-home mechanism) is set for the running user","Run under a user account with a valid home directory","Use CloudJobStore::from_path with an explicit root in tests/embedded contexts"],"exampleFix":"// before\nCODEWHALE_HOME= ./codewhale\n// after\nCODEWHALE_HOME=~/.codewhale ./codewhale","handlingStrategy":"fallback","validationCode":"let ok = std::env::var_os(\"CODEWHALE_HOME\").is_some()\n    || std::env::var_os(\"HOME\").is_some()\n    || dirs::home_dir().is_some();","typeGuard":"fn home_available() -> bool {\n    std::env::var_os(\"CODEWHALE_HOME\").is_some() || dirs::home_dir().is_some()\n}","tryCatchPattern":"match CloudJobStore::from_env() {\n    Ok(store) => store,\n    Err(e) => { eprintln!(\"{e}; set CODEWHALE_HOME\"); std::process::exit(2); }\n}","preventionTips":["Always set CODEWHALE_HOME in containers/services","Ensure service users have a home directory","Fail fast at startup with a clear message","Use from_path with explicit roots in tests"],"tags":["config","environment","filesystem"],"backgroundTag":"missing-env-var","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T10:30:35.592Z"}