jdx/mise · error

install_mise must not contain a newline

Error message

install_mise must not contain a newline: {path:?}

What it means

The configured `install_mise` path (where mise should be installed on a remote host) is validated by `validate_install_mise_path`. Because the path is embedded into remote shell commands, any embedded newline or carriage return would break or hijack the command line, so mise rejects it with this error.

Solutions

  1. Edit the config so install_mise is a single-line path string (use single-quoted TOML literal strings to avoid escape surprises)
  2. Remove trailing whitespace/newlines from the value (e.g. strip the value where it is generated)
  3. Re-run after fixing; the path must be one contiguous line like '/usr/local/bin/mise' or '~/bin/mise'

Example fix

// before
install_mise = """
/usr/local/bin/mise
"""
// after
install_mise = '/usr/local/bin/mise'
Defensive patterns

Strategy: validation

Validate before calling

if (/[\n\r]/.test(installMise)) throw new Error('install_mise must be a single line');

Type guard

const isSingleLinePath = (s: unknown): s is string =>
  typeof s === 'string' && !/[\n\r]/.test(s);

Try / catch

try {
  validate_install_mise_path(cfg.install_mise)?;
} catch (e) {
  // surface config file + line for the offending multi-line value
}

Prevention

When it happens

Trigger: `install_mise` in the remote configuration contains a literal '\n' or '\r' (multi-line TOML string, accidental line continuation, or CRLF pasted from a Windows editor).

Common situations: Hand-edited remote.toml with a wrapped/multi-line path value; config generated by a script joining strings with newline separators; copy-paste from documentation including a line break.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/system/remote.rs:2216

    Ok(command.to_string())
}

fn validated_remote_command_output(output: &str) -> Result<String> {
    validated_remote_command(output.strip_suffix('\n').unwrap_or(output))
}

fn validated_absolute_remote_path_output(output: &str, kind: &str) -> Result<String> {
    let path = output.strip_suffix('\n').unwrap_or(output);
    if !path.starts_with('/') || path.contains(['\0', '\n', '\r']) {
        bail!("{kind} returned an unsafe absolute path: {path:?}");
    }
    Ok(path.to_string())
}

fn validate_install_mise_path(path: &str) -> Result<()> {
    validate_value("mise install path", path)?;
    if path.contains(['\n', '\r']) {
        bail!("install_mise must not contain a newline: {path:?}");
    }
    if !path.starts_with('/') && !path.starts_with("~/") {
        bail!("install_mise must be an absolute path or start with ~/: {path:?}");
    }
    if path.split('/').any(|component| component == "..") {
        bail!("install_mise must not contain '..': {path:?}");
    }
    if matches!(
        path.rsplit('/').next(),
        None | Some("") | Some(".") | Some("~")
    ) {
        bail!("install_mise must name an executable file: {path:?}");
    }
    Ok(())
}

fn validate_remote_executable(command: &str) -> Result<()> {
    validate_value("mise command", command)?;

View on GitHub (pinned to 533346cc37)