herdrdev/herdr · error
{REMOTE_BINARY_ENV_VAR} must not be empty
Error message
{REMOTE_BINARY_ENV_VAR} must not be empty What it means
remote_binary_override_path reads the REMOTE_BINARY env var (REMOTE_BINARY_ENV_VAR) as an optional override for which Herdr binary to install/verify remotely. If the variable is set but its value is an empty string, it fails with ErrorKind::InvalidInput rather than silently falling back or using an empty path. This catches misconfiguration early.
Source
Thrown at src/remote/attach.rs:897
let version = lines.next().unwrap_or_default().trim();
let status = lines.next().unwrap_or_default();
Ok(version == format!("herdr {}", current_version())
&& parse_client_status_json(status)
.map(|status| status.protocol == CURRENT_PROTOCOL)
.unwrap_or(false))
}
fn remote_binary_exists(ssh: &RemoteSsh, remote_herdr: &RemoteHerdr) -> io::Result<bool> {
let command = format!("test -x {}", remote_herdr.shell_path);
Ok(ssh.sh_output(&command)?.status.success())
}
fn remote_binary_override_path() -> io::Result<Option<PathBuf>> {
let Some(value) = std::env::var_os(REMOTE_BINARY_ENV_VAR) else {
return Ok(None);
};
if value.is_empty() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
format!("{REMOTE_BINARY_ENV_VAR} must not be empty"),
));
}
let path = PathBuf::from(value);
let metadata = fs::metadata(&path).map_err(|err| {
io::Error::new(
err.kind(),
format!(
"failed to inspect {REMOTE_BINARY_ENV_VAR} path {}: {err}",
path.display()
),
)
})?;
if !metadata.is_file() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,View on GitHub (pinned to f457cff4f2)
Solutions
- Unset the variable entirely instead of setting it empty: `unset HERDR_REMOTE_BINARY` (or remove the `VAR=` line)
- Set it to a real path: `export HERDR_REMOTE_BINARY=/usr/local/bin/herdr`
- In scripts, guard with `[[ -n "$HERDR_REMOTE_BINARY" ]] && export ...` so empty values never reach Herdr
- Fix CI variable definitions to omit the variable rather than define it as empty
Example fix
# before export HERDR_REMOTE_BINARY="" # empty -> InvalidInput error herdr remote attach host # after unset HERDR_REMOTE_BINARY herdr remote attach host
Defensive patterns
Strategy: validation
Validate before calling
// Before invoking remote attach flows
if let Some(v) = std::env::var_os("HERDR_REMOTE_BINARY") {
if v.is_empty() { std::env::remove_var("HERDR_REMOTE_BINARY"); }
} Type guard
fn valid_remote_binary_override() -> Option<PathBuf> {
std::env::var_os("HERDR_REMOTE_BINARY")
.filter(|v| !v.is_empty())
.map(PathBuf::from)
} Try / catch
match remote_binary_override_path() {
Err(e) if e.kind() == std::io::ErrorKind::InvalidInput => { /* unset the empty var and retry with default */ }
other => other?,
} Prevention
- Never export the override as an empty string; unset it instead
- Guard CI/shell scripts with [[ -n "$VAR" ]] before exporting
- Validate .env files for empty-valued entries
When it happens
Trigger: Setting the Herdr remote-binary override environment variable to an empty value (e.g. `HERDR_REMOTE_BINARY= herdr remote attach ...` or an empty entry in .env/shell profile) and then invoking any remote attach/prepare flow that calls remote_binary_override_path.
Common situations: Shell scripts or CI that export the variable conditionally and leave it empty; `.env` files with a `VAR=` line; CI matrices where the variable is defined but unset-for-one-case as empty string.
Related errors
- failed to inspect {REMOTE_BINARY_ENV_VAR} path {}: {err}
- {REMOTE_BINARY_ENV_VAR} path is not a file: {}
- login shell {shell:?} is not executable
- SSH control socket path exceeds the Unix socket length limit
- failed to parse editor command {editor:?}
AI-assisted analysis of herdrdev/herdr@f457cff4f2 (2026-08-28).
Data as JSON: /api/errors/c62ae0b80b7689bd.
Report an issue: GitHub.