Schniz/fnm · error
Can't get home directory
Error message
Can't get home directory
What it means
On macOS only, when neither the modern data dir (`~/Library/Application Support/fnm`) nor the legacy `~/.fnm` exists yet, `Directories::default_base_dir` constructs an etcetera `Apple` base strategy — which resolves the home directory — and unwraps it with `.expect("Can't get home directory")`. If the home directory cannot be determined at that moment, fnm panics while computing where to put its files.
Source
Thrown at src/directories.rs:61
pub fn strategy(&self) -> &impl BaseStrategy {
&self.0
}
pub fn default_base_dir(&self) -> PathBuf {
let strategy = self.strategy();
let modern = strategy.data_dir().join("fnm");
if modern.exists() {
return modern;
}
let legacy = strategy.home_dir().join(".fnm");
if legacy.exists() {
return legacy;
}
#[cfg(target_os = "macos")]
{
let basedirs = etcetera::base_strategy::Apple::new().expect("Can't get home directory");
let legacy = basedirs.data_dir().join("fnm");
if legacy.exists() {
return legacy;
}
}
modern.ensure_exists_silently()
}
pub fn multishell_storage(&self) -> PathBuf {
let basedirs = self.strategy();
let dir = runtime_dir(basedirs)
.or_else(|| state_dir(basedirs))
.unwrap_or_else(|| cache_dir(basedirs));
dir.join("fnm_multishells")
}
}
View on GitHub (pinned to 86adc9676c)
Solutions
- Ensure HOME is set and writable: `export HOME="$HOME"` sanity check, or set it explicitly in the launching plist/agent (`EnvironmentVariables` → HOME).
- Pre-create either `~/.fnm` or `~/Library/Application Support/fnm` so the earlier existence checks return before the Apple fallback runs.
- For daemons/agents, run fnm once from a normal login shell first to materialize the directories.
- Update fnm — this fallback should degrade to a user-facing error rather than a panic.
Example fix
# before env -i fnm list # macOS first run, panic: Can't get home directory # after mkdir -p "$HOME/Library/Application Support/fnm" env -i HOME="$HOME" fnm list # ok
Defensive patterns
Strategy: validation
Validate before calling
# macOS: ensure fnm dirs exist before first run in stripped environments
mkdir -p "$HOME/Library/Application Support/fnm" || exit 1
[ -n "$HOME" ] || { echo 'HOME unset; aborting' >&2; exit 1; } Try / catch
std::panic::catch_unwind(|| run_fnm(args))
.unwrap_or_else(|_| {
eprintln!("fnm could not resolve the home directory; set HOME and retry");
std::process::exit(1);
}); Prevention
- Set EnvironmentVariables.HOME in launchd plists that invoke fnm.
- Run fnm once from a login shell so the data dirs are created before daemon contexts use it.
- Keep ~/.fnm or Application Support/fnm present after initial setup.
When it happens
Trigger: First run of any fnm command on macOS (no ~/.fnm, no Application Support/fnm) in an environment where HOME is unset or unresolvable — `env -i fnm list`, launchd agents with a stripped environment, or ssh contexts with unusual passwd entries.
Common situations: macOS LaunchAgents/LaunchDaemons that omit HOME; CI runners on macOS with minimal env; scripts run via `env -i`; first-ever invocation right after install in a sanitized shell.
Related errors
- choosing base strategy
- Can't read PATH env var
- Can't read PATH env var
- Can't get a temporary file
- Failed to grab exit code
AI-assisted analysis of Schniz/fnm@86adc9676c (2026-08-16).
Data as JSON: /api/errors/332f92a452044651.
Report an issue: GitHub.