{"record":{"id":"ddb576d36a430093","repo":"odysseus-dev/odysseus","slug":"invalid-ssh-remote-host","errorCode":null,"errorMessage":"Invalid SSH remote host","messagePattern":"Invalid SSH remote host","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"core/platform_compat.py","lineNumber":374,"sourceCode":"                        return path\n    except Exception:\n        pass\n    return None\n\n\ndef _ssh_exec_argv(\n    remote: str,\n    ssh_port: str | None,\n    *,\n    remote_cmd: str | None = None,\n    connect_timeout: int | None = None,\n    strict_host_key_checking: bool | None = None,\n) -> list[str]:\n    \"\"\"Build a consistent ssh argv for remote command execution.\"\"\"\n    remote_value = str(remote or \"\").strip()\n    remote_host = remote_value.rsplit(\"@\", 1)[-1]\n    if not remote_value or remote_value.startswith(\"-\") or not remote_host or remote_host.startswith(\"-\"):\n        raise ValueError(\"Invalid SSH remote host\")\n    argv = [\"ssh\"]\n    if connect_timeout is not None:\n        argv.extend([\"-o\", f\"ConnectTimeout={int(connect_timeout)}\"])\n    if strict_host_key_checking is not None:\n        argv.extend(\n            [\n                \"-o\",\n                \"StrictHostKeyChecking=yes\"\n                if strict_host_key_checking\n                else \"StrictHostKeyChecking=no\",\n            ]\n        )\n    if ssh_port and ssh_port != \"22\":\n        argv.extend([\"-p\", str(ssh_port)])\n    argv.append(remote)\n    if remote_cmd is not None:\n        argv.append(remote_cmd)\n    return argv","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/core/platform_compat.py#L356-L392","documentation":"ValueError raised by _ssh_exec_argv while building an ssh command line. The remote specifier is validated for argument-injection: it must be non-empty, must not start with '-', and the host part (after the last '@') must be non-empty and not start with '-'. Any violation raises before ssh is invoked.","triggerScenarios":"Passing remote='' or whitespace-only, a remote like '-oProxyCommand=...', 'user@-something', or '@hostwithemptyparts' (e.g. 'user@' or '@-flag') to any SSH remote-execution feature built on this helper.","commonSituations":"Empty SSH remote field in settings; user-entered remote beginning with a dash (treated as an ssh option); malformed user@host strings from config parsing; CI env vars with stray characters.","solutions":["Set the remote to a well-formed 'user@host' or 'host' string","Strip whitespace and reject leading '-' in the config/UI before calling","Quote nothing — this is argv-based; just avoid dashes at the start of the host","If the host genuinely starts with a digit-letter name, ensure no leading '-' or use an ssh config alias"],"exampleFix":"# before\nremote = cfg.get('ssh_remote', '')  # '' passes into _ssh_exec_argv → ValueError\n# after\nremote = (cfg.get('ssh_remote') or '').strip()\nif not remote or remote.startswith('-'):\n    raise ValueError('SSH remote must be set to user@host')","handlingStrategy":"validation","validationCode":"def is_valid_ssh_remote(remote: str) -> bool:\n    v = str(remote or '').strip()\n    host = v.rsplit('@', 1)[-1]\n    return bool(v) and not v.startswith('-') and bool(host) and not host.startswith('-')","typeGuard":null,"tryCatchPattern":"try:\n    argv = _ssh_exec_argv(remote, ssh_port)\nexcept ValueError:\n    raise ConfigError(f'SSH remote {remote!r} is invalid — use user@host') from None","preventionTips":["Validate remote strings at config-load and UI-input time","Never interpolate user input into shell/ssh option positions","Reject empty strings early instead of relying on the deep raise"],"tags":["ssh","validation","security","configuration"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}