jdx/mise · error
remote {kind} 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 applied to remote configuration scalars (host, user, SSH options, archive excludes, remote mise command): the value must be non-empty and contain no NUL byte. This error means a configured remote value is the empty string or has an embedded \0 — either impossible to pass to the OS or a sign of corrupted config.
Source
Thrown at src/system/remote.rs:1467
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 9dcfcaa0dc)
Solutions
- Find the empty/NUL value in the remote host config (mise.toml [remote.hosts.*], environment overrides like MISE_REMOTE_*)
- Remove the key entirely instead of setting it to "" when you want to clear it
- If merging layers, check mise config ls / the effective config for which layer supplies the value
- Sanitize programmatic config generation to skip empty values
Example fix
# before (mise.toml) [remote.hosts.build] ssh = "ci@build" user = "" # after [remote.hosts.build] ssh = "ci@build"
Defensive patterns
Strategy: validation
Validate before calling
# reject empty remote values when generating config
: "${MISE_REMOTE_HOST:?must be set and non-empty}" Type guard
fn valueValid(value: &str) -> bool {
!value.is_empty() && !value.contains('\0')
} Try / catch
for option in &host.ssh_options {
if !valueValid(option) {
return Err(eyre::eyre!("empty/NUL SSH option in config layer"));
}
}
host.validate()?; Prevention
- Delete config keys rather than blanking them when overriding layers
- Fail fast in templates when a remote variable is unset
- Review 'mise config ls' output for empty strings in remote entries
When it happens
Trigger: RemoteHost::validate walking ssh_options/exclude entries, remote_mise, or other scalars where the TOML value is "" (e.g. user = "" set to 'unset' a parent value) or a string smuggled a NUL (only possible via programmatic construction, since TOML cannot encode NUL directly).
Common situations: Users blanking inherited keys with empty strings when merging configs; automation templates emitting empty placeholders; values sourced from environment variables that are unset and interpolated as ''. NUL in practice appears only from bugs in tooling that builds the config.
Related errors
- invalid remote {kind}: {value}
- remote mise command must be an executable name or path: {com
- --connect-timeout must be greater than zero
- {field} must not be empty
- remote host '{}' must set at most one of mise_bin, remote_mi
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/fab2d130d2fb4c87.
Report an issue: GitHub.