{"record":{"id":"6df608fc60b2e148","repo":"jdx/mise","slug":"remote-platform-response-is-incomplete","errorCode":null,"errorMessage":"remote platform response is incomplete","messagePattern":"remote platform response is incomplete","errorType":"exception","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/remote.rs","lineNumber":1190,"sourceCode":"        if [ -e \"$loader\" ]; then libc=musl; break; fi\n      done\n    fi\n    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<_>>()","sourceCodeStart":1172,"sourceCodeEnd":1208,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/system/remote.rs#L1172-L1208","documentation":"Thrown by parse_remote_platform when the OS is not Linux and the third output line is missing (None) or is a value other than the expected literal none. The remote script always prints os, arch, then 'none' for non-Linux systems, so this arm means the output shape diverged from the protocol: a truncated response, a remote shell that mishandled the script, or a script/version skew between what ran and what the parser expects.","triggerScenarios":"Remote sh is non-POSIX or the connection truncates output so the third line never arrives; a wrapper/login environment replaces the script or injects a different third token; future script changes emit a new libc token for non-Linux OSes while the parser is old.","commonSituations":"Remotes with exotic default shells forced via sshd config; middleboxes mangling output; version mismatches during mise upgrades where the client and expectations drift.","solutions":["Reproduce the probe manually: ssh <host> sh -c 'uname -s; uname -m; echo none' and fix whatever makes the output deviate","Set remote_mise or bootstrap_command to skip platform detection entirely","Ensure the remote user's default shell is a POSIX sh and no shell wrappers rewrite commands"],"exampleFix":"# before (mise.toml)\n[bootstrap.remote.hosts.srv]\nhost = \"deploy@srv\"\n\n# after\n[bootstrap.remote.hosts.srv]\nhost = \"deploy@srv\"\nremote_mise = \"/usr/local/bin/mise\"","handlingStrategy":"validation","validationCode":"# Verify the probe protocol before running mise against a new host:\nssh deploy@srv 'uname -s; uname -m; echo none'\n# must print exactly 3 lines; if the third is missing/wrong, fix the remote shell\n# or set remote_mise / bootstrap_command","typeGuard":"fn is_wellformed_platform_output(output: &str) -> bool {\n    let lines: Vec<&str> = output.lines().collect();\n    lines.len() == 3\n        && !lines[0].trim().is_empty()\n        && !lines[1].trim().is_empty()\n        && (lines[0].eq_ignore_ascii_case(\"linux\")\n            || lines[2] == \"none\")\n}","tryCatchPattern":null,"preventionTips":["Keep the remote login shell POSIX-compatible (sh/dash/bash in POSIX mode)","When extending remote_platform_script, bump parser + script in the same commit","Wrap auto-provisioning for new remotes in a dry-run to catch protocol mismatches early"],"tags":["mise","remote-bootstrap","platform-detection","protocol-mismatch","ssh"],"backgroundTag":"output-parse-validation-failed","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}