can1357/oh-my-pi · error · ToolError
GitHub CLI did not return a pull request number.
Error message
GitHub CLI did not return a pull request number.
What it means
After running `gh pr view --json ...`, the tool expects the `number` field to be a number. If gh returns JSON without a numeric `number` (missing, null, or wrong type), the response is unusable for building branch names and push metadata, so the tool throws. This normally indicates a gh CLI/API malfunction rather than user input error, since a successful pr view always includes number.
Source
Thrown at packages/coding-agent/src/tools/gh-pr-checkout.ts:410
session: ToolSession,
signal: AbortSignal | undefined,
options: PrCheckoutOptions,
): Promise<PrCheckoutOutcome> {
const { prRef, repo, force } = options;
if (prRef?.startsWith("-")) {
throw new ToolError(`invalid PR identifier: ${prRef}. Pass a PR number, URL, or branch name.`);
}
const args = ["pr", "view"];
if (prRef) args.push(prRef);
appendRepoFlag(args, repo, prRef);
args.push("--json", GH_PR_CHECKOUT_FIELDS.join(","));
const data = await github.json<GhPrViewData>(session.cwd, args, signal, {
repoProvided: Boolean(repo),
});
const prNumber = data.number;
if (typeof prNumber !== "number") {
throw new ToolError("GitHub CLI did not return a pull request number.");
}
const headRefName = requireNonEmpty(data.headRefName, "head branch");
const headRefOid = requireNonEmpty(data.headRefOid, "head commit");
const repoRoot = await requireGitRepoRoot(session.cwd, signal);
const primaryRepoRoot = await requirePrimaryGitRepoRoot(repoRoot, signal);
const localBranch = `pr-${prNumber}`;
const worktreePath = getWorktreeDir(`${prNumber}-${hashPath(primaryRepoRoot)}`);
// Every git mutation against `repoRoot` from here on must run under the
// per-repo lock. Worktrees of the same primary repo share `.git/config`,
// `commit-graph` chain, `packed-refs`, and worktree metadata files — git
// uses O_EXCL lock files for each, with no waiter. Concurrent in-process
// callers (e.g. parallel `pr_checkout` calls) would otherwise lose lock
// races and surface "could not lock config file" / "Another git process
// seems to be running" errors. The gh API call above stays outside the
// lock so multiple checkouts can fetch PR metadata in parallel.
return withRepoLock(View on GitHub (pinned to 9690622007)
Solutions
- Run the same command manually: `gh pr view <ref> --json number,headRefName,headRefOid` — inspect what it actually returns.
- Check `gh auth status` and re-login (`gh auth login`) if the token is expired or missing scopes.
- Upgrade the GitHub CLI (`gh --version`, then update) — old versions may omit fields from the --json output.
- Verify GH_HOST/proxy environment variables point at real GitHub and that no wrapper intercepts `gh` (`which gh`).
Example fix
// before: gh returns {"message":"Bad credentials"}-shaped output → tool throws
// after: fix auth then retry
gh auth login
op pr_checkout 1234 Defensive patterns
Strategy: retry
Validate before calling
const out = Bun.$`gh pr view ${ref} --json number`.quiet().nothrow();
if (!out.exitCode || !/^\s*\{/.test(await out.text())) throw new Error("gh pr view returned unexpected output — check auth/network"); Type guard
function hasPrNumber(d: unknown): d is { number: number } {
return typeof d === "object" && d !== null && typeof (d as { number?: unknown }).number === "number";
} Try / catch
try {
await op.prCheckout({ prRef });
} catch (err) {
if (err instanceof ToolError && err.message.includes("did not return a pull request number")) {
await Bun.sleep(2000); // transient API/proxy glitch — retry once
await op.prCheckout({ prRef });
} else throw err;
} Prevention
- Run `gh auth status` before automated checkout runs.
- Keep the GitHub CLI up to date (`gh --version`).
- Check GH_HOST and proxy env vars point at real GitHub.
- Avoid wrapper scripts around `gh` that emit extra output.
When it happens
Trigger: gh CLI emitting error JSON or an unexpected shape (authentication failure returning a non-standard payload, GitHub API partial outage, proxy/captive portal returning HTML-adjacent JSON wrappers), a drastically old gh version lacking the requested --json fields, or a wrapper script shadowing `gh` that prints extra output the JSON parser misreads.
Common situations: Expired/insufficient gh auth token; corporate proxy intercepting api.github.com; gh version predating `pr view --json` field support; GH_HOST pointing at a non-GitHub endpoint.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- ${response.status} ${response.statusText}: ${text}
- flickr getSizes request failed
- Failed to create Smithery auth session: ${response.status} $
- Smithery auth polling failed: ${response.status} ${response.
- Could not determine a clone URL for ${headRepository}.
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/5a700071b0baae77.
Report an issue: GitHub.