{"record":{"id":"b918c49e334bdbc1","repo":"can1357/oh-my-pi","slug":"remote-url-has-invalid-port","errorCode":null,"errorMessage":"remote url has invalid port","messagePattern":"remote url has invalid port","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"python/robomp/src/proxy/server.py","lineNumber":324,"sourceCode":"        log.warning(\n            \"gh-proxy: refusing git op — origin has ambiguous remote urls\",\n            extra={\"expected_repo\": expected_repo, \"kind\": kind, \"count\": len(urls)},\n        )\n        raise HTTPException(400, f\"origin must have exactly one {kind} url\")\n    return urls[0]\n\n\ndef _normalized_github_https_url(url: str, expected_repo: str) -> str:\n    _validate_repo_name(expected_repo)\n    parsed = urlparse(url)\n    if (parsed.scheme or \"\").lower() != \"https\":\n        raise HTTPException(400, f\"remote url must be https://github.com/{expected_repo}[.git]\")\n    if parsed.username or parsed.password:\n        raise HTTPException(400, \"remote url must not contain embedded credentials\")\n    try:\n        port = parsed.port\n    except ValueError as exc:\n        raise HTTPException(400, \"remote url has invalid port\") from exc\n    if port is not None:\n        raise HTTPException(400, \"remote url must not specify a port\")\n    if (parsed.hostname or \"\").lower() != \"github.com\":\n        raise HTTPException(400, f\"remote url host must be github.com for repo {expected_repo!r}\")\n    if parsed.params or parsed.query or parsed.fragment:\n        raise HTTPException(400, \"remote url must not contain params, query, or fragment\")\n    path = parsed.path.strip(\"/\")\n    if path.endswith(\".git\"):\n        path = path[:-4]\n    if path.lower() != expected_repo.lower():\n        raise HTTPException(400, f\"remote url does not match repo {expected_repo!r}\")\n    return _github_url_for_repo(expected_repo)\n\n\ndef _remote_auth_for_url(url: str, expected_repo: str, token: str) -> _RemoteAuth:\n    raw = url.strip()\n    if not raw or raw != url:\n        raise HTTPException(400, \"remote url must not be empty or padded\")","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/robomp/src/proxy/server.py#L306-L342","documentation":"Raised when urlparse(url).port throws ValueError because the origin URL contains a malformed port (e.g. https://github.com:notaport/...). The proxy treats this as an invalid URL and refuses the operation with 400 rather than passing a corrupt URL to git.","triggerScenarios":"Origin URL like https://github.com:abc/acme/repo.git where text after ':' is not a valid integer port — a typo (colon instead of slash) or a corrupted remote URL.","commonSituations":"Hand-edited .git/config URLs; sed/regex rewrites of remote URLs that mangled the scheme separator; copy-paste errors like https:/github.com or https://github.com:443x/...","solutions":["Fix the URL: `git remote set-url origin https://github.com/<owner>/<repo>.git`","Verify with `git config --get remote.origin.url` and compare against the expected https URL","Avoid manual edits to .git/config; use `git remote set-url`"],"exampleFix":"// before (mangled separator)\nurl = \"https:github.com:abc/acme/repo.git\"\n// after\nurl = \"https://github.com/acme/repo.git\"","handlingStrategy":"validation","validationCode":"from urllib.parse import urlparse\n\ndef origin_url_parses(url: str) -> bool:\n    try:\n        urlparse(url).port\n        return True\n    except ValueError:\n        return False","typeGuard":null,"tryCatchPattern":"from fastapi import HTTPException\n\ntry:\n    result = client.post(\"/git/op\", json={\"repo\": \"acme/repo\"})\nexcept HTTPException as e:\n    if e.status_code == 400 and \"invalid port\" in e.detail:\n        reset_origin(worktree_dir, \"acme/repo\")  # rewrite mangled URL\n    else:\n        raise","preventionTips":["Use `git remote set-url`, never hand-edit .git/config","Test string-built URLs with urlparse before installing them as remotes","Avoid regex rewrites of remote URLs; reconstruct from canonical parts"],"tags":["git","url-parsing","remote-url","proxy"],"backgroundTag":"malformed-url","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}