denoland/deno · error

${home_env_var} is not defined

Error message

${home_env_var} is not defined

What it means

When resolving the default global installation root in `cli/tools/installer/global.rs`: if `DENO_INSTALL_ROOT` is unset, Deno falls back to `$HOME/.deno` (`$USERPROFILE` on Windows — the comment notes `$HOME` on Windows is non-standard). If that variable is not defined at all, resolution fails with `io::ErrorKind::NotFound` and this message naming the missing variable.

Source

Thrown at cli/tools/installer/global.rs:1305

  if let Some(env_dir) = env::var_os("DENO_INSTALL_ROOT")
    && !env_dir.is_empty()
  {
    let env_dir = PathBuf::from(env_dir);
    return canonicalize_path_maybe_not_exists(&env_dir).with_context(|| {
      format!(
        "Canonicalizing DENO_INSTALL_ROOT ('{}').",
        env_dir.display()
      )
    });
  }
  // Note: on Windows, the $HOME environment variable may be set by users or by
  // third party software, but it is non-standard and should not be relied upon.
  let home_env_var = if cfg!(windows) { "USERPROFILE" } else { "HOME" };
  let mut home_path =
    env::var_os(home_env_var)
      .map(PathBuf::from)
      .ok_or_else(|| {
        io::Error::new(
          io::ErrorKind::NotFound,
          format!("${home_env_var} is not defined"),
        )
      })?;
  home_path.push(".deno");
  Ok(home_path)
}

/// Remove all shim files for a given name (the main file plus .cmd/.exe on Windows).
fn remove_shim_files(
  installation_dir: &Path,
  name: &str,
) -> Result<(), AnyError> {
  let path = installation_dir.join(name);
  remove_file_if_exists(&path)?;
  if cfg!(windows) {
    remove_file_if_exists(&path.with_extension("cmd"))?;
    remove_file_if_exists(&path.with_extension("exe"))?;

View on GitHub (pinned to a961cdec3b)

Solutions

  1. Set the home variable in the container/job: `docker run -e HOME=/root ...` or `ENV HOME=/root` in the Dockerfile.
  2. Or set `DENO_INSTALL_ROOT` to an absolute writable directory so the HOME fallback is never consulted.
  3. For systemd/cron, add `Environment=HOME=/var/lib/app` (or USERPROFILE equivalent) to the unit/service definition.

Example fix

# before
$ docker run denoland/deno:latest deno install -g jsr:@luca/lume
# → $HOME is not defined

# after (either works)
$ docker run -e HOME=/root denoland/deno:latest deno install -g jsr:@luca/lume
$ DENO_INSTALL_ROOT=/usr/local/bin deno install -g jsr:@luca/lume
Defensive patterns

Strategy: validation

Validate before calling

#!/bin/sh
# POSIX: abort early with a clear message if the home variable is missing
: "${HOME:?HOME is not set — deno install -g needs it or set DENO_INSTALL_ROOT}"
# Windows (PowerShell):
# if (-not $env:USERPROFILE) { throw 'USERPROFILE is not set' }

Try / catch

try {
  await Deno.run({ cmd: ["deno", "install", "-g", pkg] });
} catch {
  // re-run with DENO_INSTALL_ROOT set to a known writable dir
}

Prevention

When it happens

Trigger: Running `deno install -g ...` (or any flow that resolves the global bin dir) in an environment where neither `DENO_INSTALL_ROOT` nor `HOME`/`USERPROFILE` is set — bare `docker run` without HOME, `env -i`, stripped systemd/cron units.

Common situations: Minimal container images running as a user without a passwd entry/HOME; CI steps that clear the environment; hardened service units using `Environment=` whitelists that omit HOME.

Related errors


AI-assisted analysis of denoland/deno@a961cdec3b (2026-08-20). Data as JSON: /api/errors/f34144d648d91c1f. Report an issue: GitHub.