Hmbown/CodeWhale · error · anyhow::Error

CODEWHALE_HOME / user home is unavailable

Error message

CODEWHALE_HOME / user home is unavailable

What it means

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.

Solutions

  1. Set CODEWHALE_HOME to a writable directory
  2. Ensure HOME (or the platform user-home mechanism) is set for the running user
  3. Run under a user account with a valid home directory
  4. Use CloudJobStore::from_path with an explicit root in tests/embedded contexts

Example fix

// before
CODEWHALE_HOME= ./codewhale
// after
CODEWHALE_HOME=~/.codewhale ./codewhale
Defensive patterns

Strategy: fallback

Validate before calling

let ok = std::env::var_os("CODEWHALE_HOME").is_some()
    || std::env::var_os("HOME").is_some()
    || dirs::home_dir().is_some();

Type guard

fn home_available() -> bool {
    std::env::var_os("CODEWHALE_HOME").is_some() || dirs::home_dir().is_some()
}

Try / catch

match CloudJobStore::from_env() {
    Ok(store) => store,
    Err(e) => { eprintln!("{e}; set CODEWHALE_HOME"); std::process::exit(2); }
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

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/28dd703686e4e6be. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/cloud_dispatch.rs:281

            ),
        }
    }
}

impl std::error::Error for DispatchError {}

/// File-backed store under `$CODEWHALE_HOME/cloud-jobs`.
#[derive(Debug, Clone)]
pub struct CloudJobStore {
    root: PathBuf,
}

impl CloudJobStore {
    /// Resolve the process Codewhale home.
    pub fn from_env() -> Result<Self> {
        let home = codewhale_home()
            .map_err(|err| anyhow!(err.to_string()))?
            .ok_or_else(|| anyhow!("CODEWHALE_HOME / user home is unavailable"))?;
        Ok(Self::from_path(home.join("cloud-jobs")))
    }

    /// Test and injected-root constructor.
    pub fn from_path(root: PathBuf) -> Self {
        Self { root }
    }

    /// Persist a job atomically. Never writes credentials.
    pub fn save(&self, job: &CloudJob) -> Result<()> {
        fs::create_dir_all(&self.root).context("failed to create cloud-jobs directory")?;
        let path = self.job_path(&job.id)?;
        let tmp = path.with_extension("json.tmp");
        let body = serde_json::to_vec_pretty(job).context("failed to encode cloud job")?;
        {
            let mut file =
                fs::File::create(&tmp).context("failed to start a private cloud job write")?;
            file.write_all(&body)

View on GitHub (pinned to 73e0f67d83)