{"record":{"id":"ebf797af3905654f","repo":"nikivdev/code","slug":"failed-to-determine-pr-url-after-creation-gh-outp","errorCode":null,"errorMessage":"failed to determine PR URL after creation (gh output had no URL and PR lookup by head returned empty)","messagePattern":"failed to determine PR URL after creation \\(gh output had no URL and PR lookup by head returned empty\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/commit.rs","lineNumber":8917,"sourceCode":"        bail!(\n            \"gh {} failed: {}\",\n            args.join(\" \"),\n            String::from_utf8_lossy(&output.stderr).trim()\n        );\n    }\n\n    // gh typically prints the PR URL, but some versions/configs can produce no stdout.\n    if let Some(url) = extract_pr_url(&combined) {\n        let number = pr_number_from_url(&url)\n            .ok_or_else(|| anyhow::anyhow!(\"failed to parse PR number from URL {}\", url))?;\n        return Ok((number, url));\n    }\n\n    if let Some(found) = gh_find_open_pr_by_head(repo_root, repo, head)? {\n        return Ok(found);\n    }\n\n    bail!(\n        \"failed to determine PR URL after creation (gh output had no URL and PR lookup by head returned empty)\"\n    );\n}\n\nfn open_in_browser(url: &str) -> Result<()> {\n    #[cfg(target_os = \"macos\")]\n    {\n        let status = Command::new(\"open\").arg(url).status()?;\n        if !status.success() {\n            bail!(\"failed to open browser\");\n        }\n        return Ok(());\n    }\n\n    #[cfg(not(target_os = \"macos\"))]\n    {\n        let status = Command::new(\"xdg-open\").arg(url).status()?;\n        if !status.success() {","sourceCodeStart":8899,"sourceCodeEnd":8935,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/commit.rs#L8899-L8935","documentation":"Raised in `gh_create_pr` (src/commit.rs:8917) when `gh pr create` SUCCEEDED but the tool could not determine the new PR's URL: neither the gh output contained a URL nor a follow-up lookup of an open PR for the same head branch (`gh_find_open_pr_by_head`) returned anything. The PR was likely created; only its URL/number could not be resolved.","triggerScenarios":"gh exits 0 but prints no URL (older gh versions, non-tty output, alternate config), and the head-based open-PR lookup returns empty because the repo/head strings don't match how GitHub lists the PR.","commonSituations":"Outdated gh CLI whose stdout omits the URL; `head` passed in a different format than GitHub reports (e.g. 'branch' vs 'owner:branch'); permission/scope restrictions so the head lookup can't see the PR; rate limiting on the follow-up lookup.","solutions":["Upgrade gh (`gh upgrade` or package manager) so `gh pr create` prints the PR URL.","Check GitHub manually for the PR on the head branch to confirm it was created.","Run `gh pr list --head <branch> --json url` and verify head string format (try `owner:branch`).","Ensure the gh token can list PRs in the target repo.","Retry idempotently: since a PR may already exist, re-running the flow usually recovers the URL via the already-exists path."],"exampleFix":"// before: head passed as plain branch, lookup misses 'owner:branch' PRs\nlet pr = gh_create_pr(root, \"org/repo\", \"feature-x\", \"main\", ...)?;\n// after\nlet pr = gh_create_pr(root, \"org/repo\", \"org:feature-x\", \"main\", ...)?;","handlingStrategy":"fallback","validationCode":"let v = Command::new(\"gh\").arg(\"--version\").output()?;\nprintln!(\"gh version: {}\", String::from_utf8_lossy(&v.stdout));\nlet out = Command::new(\"gh\").args([\"pr\",\"list\",\"--repo\",repo,\"--head\",head,\"--json\",\"url\"])\n    .current_dir(repo_root).output()?;\nif !out.status.success() { bail!(\"cannot list PRs for head: check token scope\"); }","typeGuard":"fn pr_url_present(stdout: &str, stderr: &str) -> Option<String> {\n    let combined = format!(\"{}\\n{}\", stdout, stderr);\n    combined.lines().map(str::trim)\n        .find(|l| l.starts_with(\"http\") && l.contains(\"/pull/\"))\n        .map(String::from)\n}","tryCatchPattern":"match create_pr_and_open(...) {\n    Ok(pr) => use_pr(pr),\n    Err(e) if e.to_string().contains(\"failed to determine PR URL\") => {\n        // PR was likely created; recover by listing PRs for the head branch\n        let url = gh_pr_list_by_head(repo, head)?;\n        eprintln!(\"recovered PR URL by lookup: {url}\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep the gh CLI up to date.","Pass head in the same format GitHub reports (owner:branch for cross-repo).","Ensure the token can list PRs in the target repo.","Treat this as post-creation recovery: the PR may already exist, so don't blindly recreate."],"tags":["gh-cli","github","pull-request","url-resolution"],"backgroundTag":"pr-url-resolution-failed","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}