odysseus-dev/odysseus · warning · HTTPException
Invalid ssh_port
Error message
Invalid ssh_port
What it means
HTTPException(400) from validate_ssh_port: the value does not fullmatch ^\d{1,5}$ — it contains non-digit characters (letters, whitespace, a 'tcp://' prefix) or is empty after being passed as a non-string. This is the format-level guard before the numeric range check.
Source
Thrown at routes/_validators.py:27
_SSH_PORT_RE = re.compile(r"^\d{1,5}$")
def validate_remote_host(v: str | None) -> str | None:
if v is None or v == "":
return None
if not _REMOTE_HOST_RE.match(v):
raise HTTPException(
400,
"Invalid remote_host — must be host or user@host, no SSH option syntax",
)
return v
def validate_ssh_port(v: str | None) -> str | None:
if v is None or v == "":
return None
if not _SSH_PORT_RE.fullmatch(str(v)):
raise HTTPException(400, "Invalid ssh_port")
port = int(v)
if port < 1 or port > 65535:
raise HTTPException(400, "Invalid ssh_port")
return str(port)
View on GitHub (pinned to f9235ebbf1)
Solutions
- Send the port as a plain digit string or integer, e.g. '22' or 2222
- Trim whitespace client-side before submitting
- Use the same field name the endpoint expects (ssh_port), not an alias
Example fix
# before ssh_port="22/tcp" # after ssh_port="22"
Defensive patterns
Strategy: validation
Validate before calling
ssh_port = str(ssh_port or '').strip()
if not ssh_port.isdigit():
raise ValueError('ssh_port must be digits only') Type guard
def is_digits(v) -> bool:
s = str(v or '').strip()
return bool(s) and s.isdigit() Try / catch
try:
resp = client.post('/api/remote', data={'ssh_port': p})
except HTTPError as e:
if e.response.status_code == 400 and 'ssh_port' in e.response.text:
p = re.sub(r'\D', '', str(p)); retry()
raise Prevention
- Trim whitespace client-side
- Send numeric ports, never prose like '22/tcp'
- Use typed number inputs in forms
When it happens
Trigger: Submitting ssh_port='22 ' (trailing space), 'port 22', '22/tcp', or a float like 22.0 in the request payload.
Common situations: Copy-pasting port from documentation prose; UI not trimming whitespace; serializing the field as a number with a decimal point on the client.
Related errors
- Invalid remote_host — must be host or user@host, no SSH opti
- Unknown wipe kind: {kind!r}
- ssh_port requires host
- No files uploaded
- HTTP ${res.status}${body ? ': ' + body.slice(0, 160) : ''}
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/043ffddda0e9948a.
Report an issue: GitHub.