jdx/mise · error
invalid remote {kind}: {value}
Error message
invalid remote {kind}: {value} What it means
Values that become single argv atoms in the ssh command line (host name, user, port-like scalars) are validated by validate_ssh_atom: after the non-empty/no-NUL check, a value may not start with '-' and may not contain whitespace. This prevents argument injection into the ssh command and keeps atoms atomic; this error means a configured value violates that.
Source
Thrown at src/system/remote.rs:1460
base.join(path)
};
absolutize(&path)
})
.transpose()
}
fn absolutize(path: &Path) -> Result<PathBuf> {
if path.is_absolute() {
Ok(path.to_path_buf())
} else {
Ok(std::env::current_dir()?.join(path))
}
}
fn validate_ssh_atom(kind: &str, value: &str) -> Result<()> {
validate_value(kind, value)?;
if value.starts_with('-') || value.chars().any(char::is_whitespace) {
bail!("invalid remote {kind}: {value}");
}
Ok(())
}
fn validate_value(kind: &str, value: &str) -> Result<()> {
if value.is_empty() || value.contains('\0') {
bail!("remote {kind} cannot be empty or contain NUL");
}
Ok(())
}
fn validate_staging_path(path: &str) -> Result<()> {
if !path.starts_with("/tmp/mise-bootstrap.")
|| path["/tmp/mise-bootstrap.".len()..].is_empty()
|| path.chars().any(char::is_whitespace)
{
bail!("remote mktemp returned an unsafe staging path: {path:?}");
}View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Put options in ssh_options (as separate single-atom strings) instead of embedding them in host/user
- Remove leading dashes: the host must be a hostname/alias, user a single token
- For usernames with spaces, create an SSH alias in ~/.ssh/config and reference the alias as the host
- Quote values in TOML only as needed — quoting does not bypass the check, the characters themselves are rejected
Example fix
# before (mise.toml) [remote.hosts.bad] ssh = "-J bastion build.example.com" # after [remote.hosts.bad] ssh = "build.example.com" ssh_options = ["-J", "bastion"]
Defensive patterns
Strategy: validation
Validate before calling
# lint remote host config before applying for v in "$SSH_HOST" "$SSH_USER"; do case "$v" in -*) echo "value starts with dash: $v";; esac case "$v" in *[[:space:]]*) echo "value has whitespace: $v";; esac done
Type guard
fn isSshAtom(value: &str) -> bool {
!value.is_empty()
&& !value.contains('\0')
&& !value.starts_with('-')
&& !value.chars().any(char::is_whitespace)
} Try / catch
if !isSshAtom(&host_value) {
return Err(eyre::eyre!("invalid remote host value: {host_value}"));
}
let session = SshSession::new(host)?; Prevention
- Keep host/user fields to single tokens; move options into ssh_options
- Use ~/.ssh/config aliases instead of embedding options in host strings
- Validate generated mise.toml with a config linter in CI
When it happens
Trigger: Configuration load/merge (RemoteHost::validate) or any validate_ssh_atom call site with a value like '-oProxyCommand=...' in a host/user field, or 'my user' / 'build server' containing spaces. Whitespace would split the atom into multiple ssh arguments; a leading dash would be parsed as an ssh flag.
Common situations: Copy-pasted ssh_config fragments into mise.toml remote host entries, usernames containing spaces (e.g. corporate 'first last' accounts), or accidentally putting ssh options into the host field.
Related errors
- remote {kind} cannot be empty or contain NUL
- remote mise command must be an executable name or path: {com
- --connect-timeout must be greater than zero
- remote host '{}' must set at most one of mise_bin, remote_mi
- remote host '{}' bootstrap command contains NUL
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/a6a59fc7a7b2bacc.
Report an issue: GitHub.