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

  1. Run `git -C <worktree> remote get-url origin` yourself to see the real failure (the client response hides stderr)
  2. Ensure the directory is a valid git repo/worktree with an `origin` remote; add one via `git remote add origin <url>` if missing
  3. Verify git is installed and on PATH for the proxy process environment
  4. Check proxy logs (log.warning 'gh-proxy: failed to read origin url') for the underlying git stderr
  5. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/62738ac98e97a8a4. Report an issue: GitHub.