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

  1. Run the same command manually: `gh pr view <ref> --json number,headRefName,headRefOid` — inspect what it actually returns.
  2. Check `gh auth status` and re-login (`gh auth login`) if the token is expired or missing scopes.
  3. Upgrade the GitHub CLI (`gh --version`, then update) — old versions may omit fields from the --json output.
  4. 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

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


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