{"record":{"id":"f90f959afab83b59","repo":"jdx/mise","slug":"github-relay-requires-linux-or-macos-f90f95","errorCode":null,"errorMessage":"GitHub relay requires Linux or macOS","messagePattern":"GitHub relay requires Linux or macOS","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/ssh.rs","lineNumber":191,"sourceCode":"            .destination\n            .ok_or_else(|| eyre::eyre!(\"an SSH destination is required\"))?;\n        if let Some(scope) = scope {\n            #[cfg(unix)]\n            {\n                let mut host = crate::system::remote::ad_hoc_host(\n                    &destination,\n                    std::env::current_dir()?,\n                    &[],\n                )?;\n                host.port = self.port;\n                host.identity_file = self.identity_file;\n                host.ssh_options = self.ssh_option;\n                return crate::system::remote::ssh(&host, scope, &self.command).await;\n            }\n            #[cfg(not(unix))]\n            {\n                let _ = scope;\n                bail!(\"GitHub relay requires Linux or macOS\");\n            }\n        }\n        let mut command = tokio::process::Command::new(\"ssh\");\n        command.kill_on_drop(true);\n        if let Some(port) = self.port {\n            command.args([\"-p\", &port.to_string()]);\n        }\n        if let Some(identity) = self.identity_file {\n            command.arg(\"-i\").arg(identity);\n        }\n        for option in self.ssh_option {\n            command.args([\"-o\", &option]);\n        }\n        command.arg(\"--\").arg(destination);\n        if !self.command.is_empty() {\n            command.arg(shell_words::join(&self.command));\n        }\n        crate::ui::ctrlc::exit_on_ctrl_c(false);","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/cli/ssh.rs#L173-L209","documentation":"`mise ssh` scoped relay/remote execution (src/cli/ssh.rs:191) requires a POSIX platform. When a relay scope is supplied on a non-Unix build, the `#[cfg(not(unix))]` branch discards the scope and bails unconditionally — the remote-scoped SSH path simply does not exist off POSIX.","triggerScenarios":"Passing a relay scope argument to `mise ssh` on Windows (non-unix target), where the scoped remote implementation is compiled out.","commonSituations":"Shared team scripts using scoped `mise ssh` relay commands run by Windows contributors; Windows CI executing relay-scoped dotfiles bootstrap commands; documentation examples copied verbatim to PowerShell.","solutions":["Use Linux or macOS for scoped relay commands.","Omit the scope on Windows and invoke plain ssh directly.","Gate scope-dependent automation on OS detection before calling mise ssh."],"exampleFix":"// before (Windows)\nmise ssh host --scope dotfiles -- command\n\n// after\necho \"scoped relay requires Linux/macOS\" && mise ssh host -- command","handlingStrategy":"validation","validationCode":"if (process.platform === 'win32' && args.some(a => a.startsWith('--scope'))) {\n  throw new Error('scoped relay requires Linux or macOS');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check process.platform / uname before emitting scope arguments.","Provide non-relay fallbacks for Windows users.","Split shared scripts into POSIX and Windows variants."],"tags":["ssh","relay","platform","windows"],"backgroundTag":"unsupported-platform","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"}