{"record":{"id":"1c68b8b60ea798f7","repo":"zed-industries/zed","slug":"invalid-ssh-url-url","errorCode":null,"errorMessage":"invalid ssh url: {url}","messagePattern":"invalid ssh url: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zed/src/zed/open_listener.rs","lineNumber":342,"sourceCode":"fn parse_ssh_url(url: &str) -> Result<url::Url> {\n    if let Ok(url) = url::Url::parse(url) {\n        return Ok(url);\n    }\n    // SCP/git style urls use ':' to separate from Authority and Path.\n    // They are unsupported by Url::parse, but can be normalized into a Url.\n    //   SCPUrl(\"ssh://user@host:~/relpath\") => Url(\"ssh://user@host/~/relpath\")\n    //   SCPUrl(\"ssh://user@host:/abs/path\") => Url(\"ssh://user@host/abs/path\")\n    //   SCPUrl(\"ssh://[2600::]:~/foo\") => Url(\"ssh://[2600::]/~/foo\")\n    let ssh_target = url\n        .strip_prefix(\"ssh://\")\n        .with_context(|| format!(\"invalid ssh url: {url}\"))?;\n\n    let (authority, path) = if let Some((authority, path)) = ssh_target.rsplit_once(\":~/\") {\n        (authority, format!(\"/~/{path}\"))\n    } else if let Some((authority, path)) = ssh_target.rsplit_once(\":/\") {\n        (authority, format!(\"/{path}\"))\n    } else {\n        anyhow::bail!(\"invalid ssh url: {url}\");\n    };\n\n    let (userinfo, host) = authority\n        .rsplit_once('@')\n        .map_or((None, authority), |(userinfo, host)| (Some(userinfo), host));\n    anyhow::ensure!(\n        !host.is_empty() && url::Host::parse(host).is_ok(),\n        \"invalid ssh url: {url}\"\n    );\n\n    let normalized_authority = if let Some(userinfo) = userinfo {\n        let (username, colon_password) =\n            if let Some((username, password)) = userinfo.split_once(':') {\n                (\n                    urlencoding::encode(&urlencoding::decode(username)?).into_owned(),\n                    format!(\n                        \":{}\",\n                        urlencoding::encode(&urlencoding::decode(password)?).into_owned()","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/zed/src/zed/open_listener.rs#L324-L360","documentation":"Error from parse_ssh_url when the input cannot be parsed as a standard URL and also does not carry the ssh:// prefix needed for SCP/git-style normalization. Url::parse handles only fully qualified URLs; anything else that isn't an ssh:// SCP-style target is rejected with the original string in the message.","triggerScenarios":"Thrown at crates/zed/src/zed/open_listener.rs:342 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Ensure the URL is a valid ssh URL, e.g. ssh://user@host/path or user@host:path SCP-style (which gets normalized)","Check for typos or unsupported schemes (plain hostnames without user/path are not accepted)","If piping from git remotes, verify the remote URL format is ssh or scp-like, not https with a malformed address"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"f4178619acd0d47ea1f76a2025c42962c6d6638c","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}