{"record":{"id":"fdd03baf2a61f590","repo":"jdx/mise","slug":"install-mise-must-not-contain-a-newline-path","errorCode":null,"errorMessage":"install_mise must not contain a newline: {path:?}","messagePattern":"install_mise must not contain a newline: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/remote.rs","lineNumber":2214,"sourceCode":"    Ok(command.to_string())\n}\n\nfn validated_remote_command_output(output: &str) -> Result<String> {\n    validated_remote_command(output.strip_suffix('\\n').unwrap_or(output))\n}\n\nfn validated_absolute_remote_path_output(output: &str, kind: &str) -> Result<String> {\n    let path = output.strip_suffix('\\n').unwrap_or(output);\n    if !path.starts_with('/') || path.contains(['\\0', '\\n', '\\r']) {\n        bail!(\"{kind} returned an unsafe absolute path: {path:?}\");\n    }\n    Ok(path.to_string())\n}\n\nfn validate_install_mise_path(path: &str) -> Result<()> {\n    validate_value(\"mise install path\", path)?;\n    if path.contains(['\\n', '\\r']) {\n        bail!(\"install_mise must not contain a newline: {path:?}\");\n    }\n    if !path.starts_with('/') && !path.starts_with(\"~/\") {\n        bail!(\"install_mise must be an absolute path or start with ~/: {path:?}\");\n    }\n    if path.split('/').any(|component| component == \"..\") {\n        bail!(\"install_mise must not contain '..': {path:?}\");\n    }\n    if matches!(\n        path.rsplit('/').next(),\n        None | Some(\"\") | Some(\".\") | Some(\"~\")\n    ) {\n        bail!(\"install_mise must name an executable file: {path:?}\");\n    }\n    Ok(())\n}\n\nfn validate_remote_executable(command: &str) -> Result<()> {\n    validate_value(\"mise command\", command)?;","sourceCodeStart":2196,"sourceCodeEnd":2232,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/remote.rs#L2196-L2232","documentation":"When configuring where mise should be installed on a remote host (the install_mise setting), mise validates the configured path. Because this path is interpolated into remote shell commands, embedded CR/LF characters would allow command injection, so any newline in the value is rejected with this error.","triggerScenarios":"The install_mise path (config value or remote onboarding option) contains a literal '\\n' or '\\r' character — typically from a multi-line config value, a pasted string with hidden line breaks, or reading the value from a file without trimming.","commonSituations":"YAML/TOML config where the value accidentally spans lines; shell history or editor pastes carrying trailing CR; scripts that append \"$(cat file)\" where the file has a trailing newline.","solutions":["Remove the line break from the install_mise path value in your config","Trim whitespace/newlines when loading the value programmatically before passing it to mise","Use single-line quoting in TOML/YAML (e.g. path = \"/usr/local/bin/mise\")"],"exampleFix":"// before\ninstall_mise = \"\"\"\n/usr/local/bin/mise\n\"\"\"\n// after\ninstall_mise = \"/usr/local/bin/mise\"","handlingStrategy":"validation","validationCode":"const validateInstallMisePath = (p) => { if (/[\\n\\r]/.test(p)) throw new Error('newline in install_mise path'); return p; };","typeGuard":"const hasNoNewlines = (s) => typeof s === 'string' && !/[\\n\\r]/.test(s);","tryCatchPattern":"try { setInstallMisePath(cfg.install_mise); } catch (e) { console.error('Fix install_mise value (no newlines allowed)'); process.exit(1); }","preventionTips":["Keep config values on a single line","Trim values read from files/env before assigning","Watch for editors that wrap long strings with continuation lines"],"tags":["config","path-validation","injection-prevention"],"backgroundTag":"invalid-config-value","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}