can1357/oh-my-pi · error · HTTPException
could not read origin url for worktree
Error message
could not read origin url for worktree
What it means
Raised when `git remote get-url origin` exits non-zero in the given worktree. The proxy cannot discover the origin URL, so it refuses the git operation with HTTP 400. stderr is intentionally not echoed to the client to avoid leaking local paths; details are only in the proxy log.
Source
Thrown at python/robomp/src/proxy/server.py:298
selector = ["--push", "--all"] if push else ["--all"]
try:
proc = subprocess.run(
["git", "-C", str(repo_dir), "remote", "get-url", *selector, "origin"],
capture_output=True,
text=True,
check=False,
timeout=_ORIGIN_READ_TIMEOUT_SECONDS,
env=env,
**slot_kwargs,
)
except subprocess.TimeoutExpired as exc:
raise HTTPException(504, "timeout reading origin url") from exc
if proc.returncode != 0:
# `git remote get-url` writes nothing useful to stdout on failure; do
# NOT echo stderr to the client (may leak local paths). The proxy log
# already captured the failure.
log.warning("gh-proxy: failed to read origin url", extra={"repo_dir": str(repo_dir)})
raise HTTPException(400, "could not read origin url for worktree")
return [line.strip() for line in proc.stdout.splitlines() if line.strip()]
def _read_single_remote_url(repo_dir: Path, expected_repo: str, *, push: bool, slot_uid: int | None = None) -> str:
urls = list(dict.fromkeys(_read_remote_urls(repo_dir, slot_uid=slot_uid, push=push)))
if len(urls) != 1:
kind = "push" if push else "fetch"
log.warning(
"gh-proxy: refusing git op — origin has ambiguous remote urls",
extra={"expected_repo": expected_repo, "kind": kind, "count": len(urls)},
)
raise HTTPException(400, f"origin must have exactly one {kind} url")
return urls[0]
def _normalized_github_https_url(url: str, expected_repo: str) -> str:
_validate_repo_name(expected_repo)
parsed = urlparse(url)View on GitHub (pinned to 9690622007)
Solutions
- Run `git -C <worktree> remote get-url origin` yourself to see the real failure (the client response hides stderr)
- Ensure the directory is a valid git repo/worktree with an `origin` remote; add one via `git remote add origin <url>` if missing
- Verify git is installed and on PATH for the proxy process environment
- Check proxy logs (log.warning 'gh-proxy: failed to read origin url') for the underlying git stderr
- Re-create the worktree if its .git metadata is corrupted
Example fix
// before: repo without origin remote $ git -C /srv/worktrees/feat origin # error: No such remote 'origin' // after $ git -C /srv/worktrees/feat remote add origin https://github.com/acme/repo.git
Defensive patterns
Strategy: validation
Validate before calling
import subprocess
def worktree_has_origin(repo_dir: str) -> bool:
r = subprocess.run(["git", "-C", repo_dir, "remote", "get-url", "origin"],
capture_output=True, check=False)
return r.returncode == 0 Try / catch
from fastapi import HTTPException
try:
result = client.post("/git/op", json={"repo": "acme/repo"})
except HTTPException as e:
if e.status_code == 400 and "could not read origin url" in e.detail:
fix_worktree_origin(worktree_dir) # add origin or recreate worktree
else:
raise Prevention
- Always create proxy-managed worktrees with an `origin` remote
- Validate repo_dir with `git rev-parse --is-inside-work-tree` before proxy calls
- Pin git availability/PATH in the proxy deployment
- Check proxy logs for the underlying git stderr when onboarding new worktrees
When it happens
Trigger: Calling any proxy git endpoint that resolves the worktree's origin when: repo_dir is not a git repository, the `origin` remote does not exist, git is missing/misconfigured for the spawned env, or the worktree is corrupted.
Common situations: Pointing the proxy at a directory that was never `git init`ed or was checked out with a remote other than `origin`; deleted .git directory; worktree metadata pruned; GIT_DIR/GIT_CONFIG env in slot_kwargs overriding config; git not on PATH in the proxy environment.
Related errors
- origin must have exactly one {kind} url
- origin remote is unavailable for this repository.
- pr://${parsed.number} could not resolve a default repo from
- Codex Security cloud import requires a verifiable repository
- Isolated task execution requires a Git checkout, but this wo
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/62738ac98e97a8a4.
Report an issue: GitHub.