can1357/oh-my-pi · error · ValueError

invalid PR number: {pr_number!r}

Error message

invalid PR number: {pr_number!r}

What it means

`fetch_pr_head` validates that `pr_number` is a positive integer and raises this ValueError otherwise. PR refs map to `refs/pull/{n}/head`, so zero, negative numbers, or (from untyped callers) non-numeric values cannot produce a valid ref and are rejected before spawning git.

Source

Thrown at python/robomp/src/git_ops.py:626

def fetch_pr_head(
    repo_dir: Path,
    pr_number: int,
    *,
    token: str | None,
    remote_url: str | None = None,
    auth_url: str | None = None,
    safe_directory: Path | None = None,
) -> None:
    """Fetch ``refs/pull/<n>/head`` into FETCH_HEAD with all reachable blobs.

    Immediately followed by ``git worktree add --detach FETCH_HEAD`` for PR
    review checkouts. See :func:`fetch_ref` for why ``--refetch --no-filter``
    is required: without the blob backfill, the worktree-add triggers a
    promisor lazy fetch that fails under proxy-transport deployments
    (oh-my-pi#1818).
    """
    if pr_number <= 0:
        raise ValueError(f"invalid PR number: {pr_number!r}")
    remote = remote_url or "origin"
    ref = f"refs/pull/{pr_number}/head" if remote_url else f"pull/{pr_number}/head"
    args = ["fetch", "--refetch", "--no-filter", remote, ref]
    _check(
        _run_git(
            args,
            cwd=repo_dir,
            token=token,
            auth_url=auth_url,
            extra_env=_explicit_remote_env(remote_url, cwd=repo_dir),
            safe_directory=safe_directory,
        ),
        ["git", *args],
    )


@dataclass(slots=True, frozen=True)
class PushResult:

View on GitHub (pinned to 9690622007)

Solutions

  1. Pass the actual positive PR number as an int
  2. Sanitize the source of the number — extract digits from URLs like /pull/123 before calling
  3. Validate input at your API boundary: `if not isinstance(n, int) or n <= 0: skip`

Example fix

// before
num = int(re.search(r"pull/(\d*)", url).group(1))  # may be 0/empty
fetch_pr_head(repo_dir, num)
// after
m = re.search(r"pull/(\d+)", url)
if not m:
    raise ValueError(f"no PR number in {url!r}")
fetch_pr_head(repo_dir, int(m.group(1)))
Defensive patterns

Strategy: validation

Validate before calling

def fetch_pr_checked(repo, pr_number):
    if not isinstance(pr_number, int) or isinstance(pr_number, bool) or pr_number <= 0:
        raise ValueError(f"PR number must be a positive int, got {pr_number!r}")
    return fetch_pr_head(repo, pr_number=pr_number)

Type guard

def is_valid_pr_number(n) -> bool:
    return isinstance(n, int) and not isinstance(n, bool) and n > 0

Try / catch

try:
    fetch_pr_head(repo_dir, pr_number=n)
except ValueError as exc:
    log.warning("skipping bad PR reference: %s", exc)

Prevention

When it happens

Trigger: Calling `fetch_pr_head(repo_dir, pr_number=0)`, a negative number, or a value like `"#123"`/`None` that reaches the `pr_number <= 0` check.

Common situations: Parsing PR numbers out of branch names or URLs with a regex that captures empty/garbage groups, off-by-one loops starting at 0, API responses where the number field was missing.

Related errors


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