Hmbown/CodeWhale · error

A positive pull request number is required

Error message

A positive pull request number is required

What it means

view_with in the PR review tool validates the pull request number before shelling out to `gh pr view`. A number of 0 (the u32 zero, typically an unset/default) is not a valid PR number, so it throws this error immediately rather than making a doomed gh call. It is raised in view_with, which is called by fetch_view and diff_with.

Solutions

  1. Supply the actual positive PR number from the user's request or URL.
  2. Parse and validate the PR number at the tool-argument boundary before invoking the tool.
  3. If the number legitimately may be absent, check for 0 upstream and surface a clearer 'no PR selected' message.

Example fix

// before
review_pr(number, repo).await?; // number defaults to 0
// after
let number: u32 = args.number.unwrap_or_else(|| bail!("--pr number is required"));
review_pr(number, repo).await?;
Defensive patterns

Strategy: validation

Validate before calling

const prNumber = Number(args.number);
if (!Number.isInteger(prNumber) || prNumber <= 0) {
  throw new Error("a positive pull request number is required");
}

Type guard

function isValidPrNumber(n: unknown): n is number {
  return typeof n === "number" && Number.isInteger(n) && n > 0;
}

Prevention

When it happens

Trigger: Calling review_pr view/diff with number=0 — usually a default-initialized u32 that was never filled in from user input.

Common situations: Tool arguments not parsed from the user's request, leaving the default 0; a placeholder call in generated code; a UI passing an unselected PR number.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/7c13a55bb4012df1. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tools/review_pr.rs:83

        [_, mode] => mode.len() == 6 && mode.bytes().all(|byte| matches!(byte, b'0'..=b'7')),
        _ => false,
    };
    if !valid_fields {
        return false;
    }
    let Some((old, new)) = fields[0].split_once("..") else {
        return false;
    };
    commit_id(old) && commit_id(new) && old.len() == new.len()
}

fn view_with(
    number: u32,
    repo: Option<&str>,
    run: &mut impl FnMut(Program, &[String]) -> Result<String>,
) -> Result<GhPullRequest> {
    if number == 0 {
        bail!("A positive pull request number is required");
    }
    let mut args = pr_args("view", number, repo);
    args.extend(["--json".into(), VIEW_FIELDS.into()]);
    let view: GhPullRequest = serde_json::from_str(&run(Program::Gh, &args)?)
        .context("gh pr view returned incomplete PR metadata")?;
    if !commit_id(&view.base_sha) || !commit_id(&view.head_sha) {
        bail!("gh pr view did not return exact base and head commit IDs");
    }
    Ok(view)
}

pub(crate) fn fetch_view(
    number: u32,
    repo: Option<&str>,
    workspace: &Path,
) -> Result<GhPullRequest> {
    view_with(number, repo, &mut |program, args| {
        run_command(workspace, program, args)

View on GitHub (pinned to 73e0f67d83)