{"record":{"id":"a4a5921100a09a98","repo":"sinelaw/fresh","slug":"invalid-ssh-url-to-open-a-local-file-with-this-name-prefix","errorCode":null,"errorMessage":"invalid ssh:// URL {:?}: {}. To open a local file with this name, prefix it with ./","messagePattern":"invalid ssh:// URL (.+?): (.+?)\\. To open a local file with this name, prefix it with \\./","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/src/main.rs","lineNumber":1497,"sourceCode":"/// argument is a hard error, never a local-path fallback.  Silently\n/// opening a local buffer named `ssh://host/...` hid the failure and\n/// invited saving to a bogus local path (#2221).  A genuine local\n/// file whose name starts with `ssh://` can still be opened as\n/// `./ssh://...`.\nfn parse_location(input: &str) -> AnyhowResult<ParsedLocation> {\n    parse_location_with_default_user(input, default_ssh_user().as_deref())\n}\n\n/// `parse_location` with the `$USER`/`$USERNAME` fallback injected,\n/// so tests can pin it without mutating the process environment.\nfn parse_location_with_default_user(\n    input: &str,\n    default_user: Option<&str>,\n) -> AnyhowResult<ParsedLocation> {\n    if let Some(rest) = input.strip_prefix(\"ssh://\") {\n        return match parse_ssh_url_rest(rest, default_user) {\n            Ok(loc) => Ok(ParsedLocation::Remote(loc)),\n            Err(reason) => Err(anyhow::anyhow!(\n                \"invalid ssh:// URL {:?}: {}. \\\n                 To open a local file with this name, prefix it with ./\",\n                input,\n                reason\n            )),\n        };\n    }\n\n    // scp-style: user@host:path. Must have @ before the first : to\n    // count as remote (skips Windows drive letters like `C:\\...`).\n    if let Some(at_pos) = input.find('@') {\n        let user = &input[..at_pos];\n        let after_at = &input[at_pos + 1..];\n\n        if let Some(colon_pos) = after_at.find(':') {\n            let host = &after_at[..colon_pos];\n            let path_and_rest = &after_at[colon_pos + 1..];\n","sourceCodeStart":1479,"sourceCodeEnd":1515,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/src/main.rs#L1479-L1515","documentation":"parse_location accepts user input for a location to open. When the input starts with ssh:// but the rest fails to parse, it converts the parse reason into this error and helpfully suggests that if the user actually meant a local file literally named like a URL, they should prefix the path with ./ to force local interpretation.","triggerScenarios":"A user passes an argument like ssh://bad host form on the command line or in the open prompt: missing host, bad port, or malformed user@host — anything parse_ssh_url_rest rejects.","commonSituations":"Typing ssh://host: (trailing colon, empty port); copying an scp-style shorthand (ssh://host:path with colon-separated path) the parser doesn't accept; intentionally opening a file named 'ssh://...' in the working directory without ./ prefix.","solutions":["Fix the URL syntax: ssh://[user@]host[:port]/path with a valid host and port","If you meant a local file that literally starts with ssh://, open it as ./ssh://... per the error hint","Drop scp-style colon paths; use the slash-separated ssh URL form instead","Verify user/host characters are URL-safe (escape or quote special characters)"],"exampleFix":"// before\nfresh ssh://server:22:~/project\n// after\nfresh ssh://user@server:22/home/user/project","handlingStrategy":"validation","validationCode":"fn parse_or_local(input: &str) -> Result<ParsedLocation, String> {\n    if input.starts_with(\"ssh://\") && !input.contains(\"@\") && !input.contains(\":\") {\n        return Err(format!(\"invalid ssh URL '{input}'; use ./{} for a local file\", input));\n    }\n    Ok(ParsedLocation::Local(input.into()))\n}","typeGuard":null,"tryCatchPattern":"match parse_location(input, default_user) {\n    Err(e) if e.to_string().contains(\"invalid ssh:// URL\") => {\n        eprintln!(\"{e:#}\"); // hint already suggests ./ prefix for local files\n    }\n    other => other?,\n}","preventionTips":["Use full, well-formed ssh URLs: ssh://[user@]host[:port]/path, no scp-style colons","Prefix local files whose names resemble URLs with ./ to force local parsing","Avoid trailing colons (ssh://host:) — they produce empty ports and fail parsing","Quote inputs with special characters so the shell doesn't split the URL"],"tags":["ssh","url-parsing","cli"],"backgroundTag":"invalid-url-format","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}