{"record":{"id":"6bd0443da80ac397","repo":"wezterm/wezterm","slug":"detach-not-implemented-for-remotesshdomain","errorCode":null,"errorMessage":"detach not implemented for RemoteSshDomain","messagePattern":"detach not implemented for RemoteSshDomain","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mux/src/ssh.rs","lineNumber":802,"sourceCode":"\n    fn domain_id(&self) -> DomainId {\n        self.id\n    }\n\n    fn domain_name(&self) -> &str {\n        &self.name\n    }\n\n    async fn attach(&self, _window_id: Option<crate::WindowId>) -> anyhow::Result<()> {\n        Ok(())\n    }\n\n    fn detachable(&self) -> bool {\n        false\n    }\n\n    fn detach(&self) -> anyhow::Result<()> {\n        bail!(\"detach not implemented for RemoteSshDomain\");\n    }\n\n    fn state(&self) -> DomainState {\n        // Just pretend that we are always attached, as we don't\n        // have a defined attach operation that is distinct from\n        // a spawn.\n        DomainState::Attached\n    }\n}\n\n#[derive(Debug)]\nstruct KillerInner {\n    killer: Option<Box<dyn ChildKiller + Send + Sync>>,\n    /// If we haven't populated `killer` by the time someone has called\n    /// `kill`, then we use this to remember to kill as soon as we recv\n    /// the child process.\n    pending_kill: bool,\n}","sourceCodeStart":784,"sourceCodeEnd":820,"githubUrl":"https://github.com/wezterm/wezterm/blob/3ff7522b9617ec920f7fbdb22b57e93d42d93ee9/mux/src/ssh.rs#L784-L820","documentation":"RemoteSshDomain (mux/src/ssh.rs:802) implements detach() as an unconditional bail because a wezterm-ssh domain has no detachable server-side session: attach is a no-op and detachable() deliberately returns false. Detach is only meaningful for domains backed by a persistent wezterm mux (unix/tls domains). Calling domain.detach() on an ssh domain — directly or via a detach action — hits this error.","triggerScenarios":"A keybinding or CLI flow invoking DetachDomain/detach while the current domain is an ssh domain (wezterm ssh sessions, ssh_domains); generic code calling detach() without checking detachable().","commonSituations":"Config with a hardwired detach key used inside `wezterm ssh`; automation written against unix domains reused on ssh domains.","solutions":["Guard the call: only detach when domain.detachable() is true (ssh domains return false).","Use the default domain-agnostic detach action, which targets the current domain only when it is detachable.","In user code, treat detachable() == false as 'not an error, nothing to do' rather than calling detach()."],"exampleFix":"// before\nif domain.domain_id() != *default_domain_id {\n    domain.detach()?; // bails for RemoteSshDomain\n}\n\n// after\nif domain.detachable() {\n    domain.detach()?;\n}","handlingStrategy":"validation","validationCode":"if domain.detachable() {\n    domain.detach()?;\n} else {\n    // ssh domains (RemoteSshDomain) are not detachable; this is not an error\n    log::debug!(\"domain {} is not detachable; skipping\", domain.domain_id());\n}","typeGuard":null,"tryCatchPattern":"match domain.detach() {\n    Err(ref e) if e.to_string().contains(\"detach not implemented\") => {\n        // expected for ssh domains: ignore, nothing to detach\n    }\n    other => other?,\n}","preventionTips":["Always branch on detachable() before calling detach().","Scope detach keybindings to unix/tls domains.","Remember ssh domains report DomainState::Attached but are never detachable by design."],"tags":["wezterm","ssh","domain","detach","not-implemented","rust"],"backgroundTag":"operation-not-supported","analyzedSha":"3ff7522b9617ec920f7fbdb22b57e93d42d93ee9","analyzedAt":"2026-08-20T04:47:31.434Z","contentChangedAt":"2026-08-20T04:47:31.434Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}