jdx/mise · error

remote cannot be empty or contain NUL

Error message

remote {kind} cannot be empty or contain NUL

What it means

`validate_value` is the base check for every remote field (kind describes which): the value must be non-empty and must not contain a NUL byte, since NUL cannot appear in command-line arguments and empty values indicate missing configuration. It underpins the stricter `validate_ssh_atom` checks.

Solutions

  1. Set the missing remote field (host/user/path) to a concrete non-empty value in config or environment
  2. Check where the value comes from (env var, mise.toml) for truncation or garbage bytes and fix the source
  3. Re-export/re-set the variable without embedded NULs, then rerun

Example fix

// before
# mise.toml or env
MISE_REMOTE_HOST=""    # empty -> bail
// after
MISE_REMOTE_HOST="deploy@build.example.com"
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_remote_value(v: &str) -> bool {
    !v.is_empty() && !v.contains('\\0')
}
// before calling:
if !is_valid_remote_value(&host) { eprintln!("remote host unset or invalid"); std::process::exit(1); }

Try / catch

if let Err(e) = op() {
    if e.to_string().contains("cannot be empty or contain NUL") {
        eprintln!("set the remote host/user config and retry: {e}");
    }
    return Err(e.into());
}

Prevention

When it happens

Trigger: An unset or blank remote host/user/path is passed to the remote transport, or a value containing a literal NUL (e.g. from corrupted env vars or binary-contaminated config) reaches the validator.

Common situations: Environment variable like MISE_REMOTE_HOST left empty; templated config where a variable expanded to nothing; programmatic callers constructing args from C-string sources that got truncated at a NUL.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/fab2d130d2fb4c87. Report an issue: GitHub.

Appendix: source

Thrown at src/system/remote.rs:2179

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:?}");
    }
    Ok(())
}

fn validated_remote_command(command: &str) -> Result<String> {
    if !command.starts_with('/') || command.contains(['\0', '\n', '\r']) {
        bail!("bootstrap_command returned an unsafe mise path: {command:?}");
    }

View on GitHub (pinned to 533346cc37)