{"record":{"id":"6b82cc849fa117c4","repo":"sinelaw/fresh","slug":"ssh-url-expects-an-ssh-url-got","errorCode":null,"errorMessage":"--ssh-url expects an ssh:// URL, got {:?}","messagePattern":"--ssh-url expects an ssh:// URL, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/src/main.rs","lineNumber":1456,"sourceCode":"        .any(|loc| matches!(loc, ParsedLocation::Local(_)))\n    {\n        anyhow::bail!(\n            \"Cannot mix local and remote files. Use either local paths or remote paths (ssh:// or user@host:path).\"\n        );\n    }\n\n    Ok(Some(remote_location_to_ssh_url(first)))\n}\n\n/// Parse a standalone `ssh://…` URL passed via the internal\n/// `--ssh-url` flag.  Accepts only the URL form (not scp-style) and\n/// the URL must carry a path; anything else is a hard error because\n/// this input comes from our own `spawn_server_detached` and a\n/// malformed URL there means we corrupted it on the way over.\nfn parse_ssh_url_arg(url: &str) -> AnyhowResult<RemoteLocation> {\n    let rest = url\n        .strip_prefix(\"ssh://\")\n        .ok_or_else(|| anyhow::anyhow!(\"--ssh-url expects an ssh:// URL, got {:?}\", url))?;\n    parse_ssh_url_rest(rest, default_ssh_user().as_deref()).map_err(|reason| {\n        anyhow::anyhow!(\n            \"--ssh-url is not a valid ssh:// URL ({}): {:?}\",\n            reason,\n            url\n        )\n    })\n}\n\n/// Parse a location that may be local, scp-style remote, or an\n/// `ssh://` URL.\n///\n/// Accepted forms:\n/// - local: `file`, `file:line`, `file:line:col`\n/// - scp-style remote: `user@host:path[:line[:col]]`\n/// - URL-style remote: `ssh://[user@]host[:port]/path[:line[:col]]`\n///\n/// When `ssh://` omits the user, the current login name (`$USER` /","sourceCodeStart":1438,"sourceCodeEnd":1474,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/src/main.rs#L1438-L1474","documentation":"parse_ssh_url_arg validates the --ssh-url CLI argument passed by spawn_server_detached when re-invoking the editor for a remote session. The URL must start with ssh://; anything else is a hard error because the argument is generated internally — a malformed value means the URL was corrupted between the two processes.","triggerScenarios":"The editor re-executes itself with --ssh-url and the argument lost its ssh:// prefix — quoting/word-splitting issues in the spawn command, shell interpolation mangling the URL, or a user manually invoking the binary with a bad --ssh-url value.","commonSituations":"Manual testing of the binary with --ssh-url host:path instead of ssh://host/path; a bug in spawn_server_detached that truncates or rewrites the argument; special characters in host/user names breaking quoting.","solutions":["Check the exact value passed to --ssh-url; it must literally begin with ssh://","If a user typo'd it, use the correct form: --ssh-url ssh://user@host/path","If spawn_server_detached produced it, debug the argument construction/quoting there — this is an internal corruption per the doc comment","Log the full argv at spawn time to catch mangling by intermediate shells"],"exampleFix":"// before\nfresh --ssh-url host.example.com/repo\n// after\nfresh --ssh-url ssh://host.example.com/repo","handlingStrategy":"validation","validationCode":"fn valid_ssh_url_arg(url: &str) -> bool {\n    url.starts_with(\"ssh://\")\n}\n// assert before spawning: debug_assert!(valid_ssh_url_arg(&built_url));","typeGuard":null,"tryCatchPattern":"match parse_ssh_url_arg(&arg) {\n    Err(e) if e.to_string().starts_with(\"--ssh-url expects\") => {\n        eprintln!(\"internal error: malformed --ssh-url '{arg}'; expected ssh://…\");\n        std::process::exit(2);\n    }\n    other => other?,\n}","preventionTips":["Always build the --ssh-url value with the ssh:// prefix in spawn_server_detached","Log full argv at re-exec time to catch quoting/word-splitting mangling","Quote the URL argument when constructing the re-exec command line","Never hand-edit the generated --ssh-url; let spawn_server_detached construct it"],"tags":["cli","ssh","argument-parsing"],"backgroundTag":"invalid-cli-argument","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"}