{"record":{"id":"6b29aa8407be2027","repo":"cross-rs/cross","slug":"pr-should-be-a-number-got","errorCode":null,"errorMessage":"pr should be a number, got {:?}","messagePattern":"pr should be a number, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xtask/src/ci/target_matrix.rs","lineNumber":186,"sourceCode":"            Ok::<_, eyre::Report>(b && has_no_ci_target_label(pr)?)\n        })?\n    {\n        app.none = true;\n    }\n    Ok(())\n}\n\nfn parse_gh_labels(pr: &str) -> cross::Result<Vec<String>> {\n    #[derive(Deserialize)]\n    struct PullRequest {\n        labels: Vec<PullRequestLabels>,\n    }\n\n    #[derive(Deserialize)]\n    struct PullRequestLabels {\n        name: String,\n    }\n    eyre::ensure!(\n        pr.chars().all(|c| c.is_ascii_digit()),\n        \"pr should be a number, got {:?}\",\n        pr\n    );\n    let stdout = Command::new(\"gh\")\n        .args([\"pr\", \"view\", pr, \"--json\", \"labels\"])\n        .run_and_get_stdout(&mut Verbosity::Quiet.into())?;\n    let pr_info: PullRequest = serde_json::from_str(&stdout)?;\n    Ok(pr_info.labels.into_iter().map(|l| l.name).collect())\n}\n\nfn has_no_ci_target_label(pr: &str) -> cross::Result<bool> {\n    Ok(parse_gh_labels(pr)?.contains(&\"no-ci-targets\".to_owned()))\n}\n\nfn has_no_ci_tests_label(pr: &str) -> cross::Result<bool> {\n    Ok(parse_gh_labels(pr)?.contains(&\"no-ci-tests\".to_owned()))\n}","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/cross-rs/cross/blob/8c1a8aa4b661711f4b7b6ac07c2e8929ce2f7d27/xtask/src/ci/target_matrix.rs#L168-L204","documentation":"parse_gh_labels shells out to `gh pr view <pr> --json labels` to fetch labels for a pull request. Before invoking the command it validates with eyre::ensure! that the `pr` string consists solely of ASCII digits, because it is passed directly as a CLI argument. Any non-digit character (including an empty string or a full URL) fails with 'pr should be a number, got {pr:?}'.","triggerScenarios":"Calling apply_ci_labels / has_no_ci_target_label / has_no_ci_tests_label with a `pr` argument that is not a plain numeric ID: e.g. passing a PR URL (\"https://github.com/org/repo/pull/123\"), a value with a '#' prefix (\"#123\"), whitespace, or an empty string pulled from a mis-parsed GITHUB_REF or CI event payload.","commonSituations":"Extracting the PR number from GITHUB_REF ('refs/pull/123/merge') with a faulty split; a developer passing a branch name or URL manually; an environment variable that is unset or contains stray characters being fed as the pr argument in CI scripts.","solutions":["Extract only the numeric portion before calling: strip the URL/'#' prefix and pass just the digits (e.g. refs/pull/123/merge -> \"123\").","Check the env var or input that supplied the pr value for emptiness or surrounding characters and fix the parsing that produced it.","If a URL is what you have, run `gh pr view <url>` yourself instead, or derive the number with `basename`/regex before invoking the xtask command."],"exampleFix":"// before\nlet pr = env::var(\"GITHUB_REF\")?; // \"refs/pull/123/merge\"\napply_ci_labels(&pr)?;\n\n// after\nlet pr = env::var(\"GITHUB_REF\")?\n    .split('/')\n    .nth(2)\n    .expect(\"GITHUB_REF to contain pr number\")\n    .to_string(); // \"123\"\napply_ci_labels(&pr)?;","handlingStrategy":"validation","validationCode":"fn is_pr_number(pr: &str) -> bool { !pr.is_empty() && pr.chars().all(|c| c.is_ascii_digit()) }\nassert!(is_pr_number(&pr), \"pr must be a numeric id, got {pr:?}\");","typeGuard":"fn parse_pr_number(s: &str) -> Option<u64> { s.parse::<u64>().ok() }","tryCatchPattern":"match parse_pr_number(&pr) {\n    Some(n) => apply_ci_labels(&n.to_string())?,\n    None => eyre::bail!(\"GITHUB_REF/pr input is not a numeric PR id: {pr:?}\"),\n}","preventionTips":["Parse the numeric PR id out of GITHUB_REF with split('/') rather than passing the raw value.","Strip '#' and URL prefixes at the input boundary of your CI script.","Validate inputs with eyre::ensure! at the script/entry level before invoking xtask."],"tags":["github-cli","cli","input-validation","ci"],"backgroundTag":"invalid-argument-format","analyzedSha":"8c1a8aa4b661711f4b7b6ac07c2e8929ce2f7d27","analyzedAt":"2026-09-13T15:10:43.988Z","contentChangedAt":"2026-09-13T15:10:43.988Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}