{"record":{"id":"e142aac1b675caec","repo":"jdx/mise","slug":"remote-platform-response-is-invalid","errorCode":null,"errorMessage":"remote platform response is invalid","messagePattern":"remote platform response is invalid","errorType":"exception","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/remote.rs","lineNumber":1193,"sourceCode":"    printf '%s\\n' \"${libc:-unknown}\"\n    ;;\n  *) printf '%s\\n' none ;;\nesac\"#\n}\n\nfn parse_remote_platform(output: &str) -> Result<RemotePlatform> {\n    let mut lines = output.lines();\n    let os = normalize_os(lines.next().unwrap_or_default());\n    let arch = normalize_arch(lines.next().unwrap_or_default());\n    let libc = match (os.as_str(), lines.next()) {\n        (\"linux\", Some(\"glibc\")) => Some(LibcFlavor::Glibc),\n        (\"linux\", Some(\"musl\")) => Some(LibcFlavor::Musl),\n        (\"linux\", _) => bail!(\"remote Linux libc family could not be identified\"),\n        (_, Some(\"none\")) => None,\n        _ => bail!(\"remote platform response is incomplete\"),\n    };\n    if os.is_empty() || arch.is_empty() || lines.next().is_some() {\n        bail!(\"remote platform response is invalid\");\n    }\n    Ok(RemotePlatform { os, arch, libc })\n}\n\n#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]\nstruct AbiVersion(Vec<u32>);\n\nimpl fmt::Display for AbiVersion {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.write_str(\n            &self\n                .0\n                .iter()\n                .map(u32::to_string)\n                .collect::<Vec<_>>()\n                .join(\".\"),\n        )\n    }","sourceCodeStart":1175,"sourceCodeEnd":1211,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/system/remote.rs#L1175-L1211","documentation":"Thrown by parse_remote_platform when the response is structurally malformed: the OS or arch line is empty, or there are extra lines beyond the expected three. The classic cause is remote shell startup noise — .bashrc/.profile or sshd banners printing MOTD/debug text during the non-interactive sh -c probe — so the parser sees a fourth line and rejects the whole response.","triggerScenarios":"Remote login rc files (e.g. a .bashrc that echoes text unconditionally) emit output during 'ssh host sh -c ...'; system login banners configured for non-interactive sessions; any extra stdout line from the remote side of the probe.","commonSituations":"Shared servers with decorative .bashrc content (fortune, weather scripts, echo statements); hardened sshd with forced command wrappers; monitoring agents that print to sessions.","solutions":["Guard remote rc files so they print only for interactive shells: case $- in *i*) ... ;; esac","Verify with: ssh <host> 'uname -s; uname -m; echo done' — anything beyond the expected lines must be silenced","Set remote_mise or bootstrap_command to avoid platform detection if the noise cannot be removed"],"exampleFix":"# before (~/.bashrc on remote)\necho \"Welcome to buildserver!\"\nfortune\n\n# after\ncase $- in *i*) ;; *) return ;; esac\necho \"Welcome to buildserver!\"\nfortune","handlingStrategy":"validation","validationCode":"# Detect shell-startup noise before it corrupts platform detection:\nout=$(ssh deploy@srv 'sh -c \"uname -s; uname -m; echo sentinel\"')\n[ \"$(printf '%s\\n' \"$out\" | wc -l)\" -eq 3 ] || echo \"remote prints extra output during non-interactive ssh - silence rc files\"","typeGuard":"fn is_wellformed_platform_output(output: &str) -> bool {\n    let mut lines = output.lines();\n    let os = lines.next().unwrap_or_default();\n    let arch = lines.next().unwrap_or_default();\n    let third = lines.next();\n    !os.trim().is_empty() && !arch.trim().is_empty() && third.is_some() && lines.next().is_none()\n}","tryCatchPattern":null,"preventionTips":["Guard remote rc files: 'case $- in *i*) ;; *) return ;; esac' at the top","Never echo/MOTD from .bashrc/.profile unconditionally on servers used for automation","Prefer sshd without forced banners for automation accounts"],"tags":["mise","remote-bootstrap","ssh","shell-startup-noise","platform-detection","parsing"],"backgroundTag":"output-parse-validation-failed","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}