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

  1. Put options in ssh_options (as separate single-atom strings) instead of embedding them in host/user
  2. Remove leading dashes: the host must be a hostname/alias, user a single token
  3. For usernames with spaces, create an SSH alias in ~/.ssh/config and reference the alias as the host
  4. 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

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


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/a6a59fc7a7b2bacc. Report an issue: GitHub.