{"record":{"id":"cc6ff8a96363fc39","repo":"nikivdev/code","slug":"gh-failed","errorCode":null,"errorMessage":"gh {} failed: {}","messagePattern":"gh (.+?) failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/commit.rs","lineNumber":8515,"sourceCode":"        .args([\"--version\"])\n        .stdout(Stdio::null())\n        .stderr(Stdio::null())\n        .status()\n        .context(\"failed to run `gh` (GitHub CLI)\")?;\n    if !status.success() {\n        bail!(\"`gh` is installed but not working\");\n    }\n    Ok(())\n}\n\nfn gh_capture_in(repo_root: &Path, args: &[&str]) -> Result<String> {\n    let output = Command::new(\"gh\")\n        .current_dir(repo_root)\n        .args(args)\n        .output()\n        .with_context(|| format!(\"failed to run gh {}\", args.join(\" \")))?;\n    if !output.status.success() {\n        bail!(\n            \"gh {} failed: {}\",\n            args.join(\" \"),\n            String::from_utf8_lossy(&output.stderr).trim()\n        );\n    }\n    Ok(String::from_utf8_lossy(&output.stdout).to_string())\n}\n\nfn github_repo_from_remote_url(url: &str) -> Option<String> {\n    let trimmed = url.trim().trim_end_matches('/');\n    if trimmed.is_empty() {\n        return None;\n    }\n\n    // https://github.com/owner/repo(.git)\n    if let Some(rest) = trimmed.strip_prefix(\"https://github.com/\") {\n        return Some(rest.trim_end_matches(\".git\").to_string());\n    }","sourceCodeStart":8497,"sourceCodeEnd":8533,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/commit.rs#L8497-L8533","documentation":"Generic failure wrapper for `gh_capture_in`: when a spawned `gh <args>` command exits non-zero, the tool bails with the command name and gh's trimmed stderr. Because gh prints actionable errors (auth, permissions, rate limits), the appended text is the primary diagnostic.","triggerScenarios":"Any captured gh call (e.g. `gh pr view`, `gh repo view`, `gh api`) that exits non-zero — typically unauthenticated sessions (`gh auth status` failing), missing scopes, nonexistent PR/repo, or network failures.","commonSituations":"Running `gh auth login` never done or token expired; GH_TOKEN/GITHUB_TOKEN env var pointing at a revoked token; operating in a directory with no git remote so gh can't infer the repo; corporate proxy blocking api.github.com.","solutions":["Read the gh stderr in the message and run `gh auth status`","Authenticate: `gh auth login` (or fix GH_TOKEN/GITHUB_TOKEN)","Re-run the exact gh command manually to confirm the cause","Check network/proxy access to api.github.com"],"exampleFix":"// before\nError: gh pr view failed: gh: To use GitHub CLI in a GitHub Actions workflow, set the GH_TOKEN environment variable\n// after\n$ export GH_TOKEN=$(gh auth token)  # or run `gh auth login`\n$ tool create-review","handlingStrategy":"try-catch","validationCode":"let auth = Command::new(\"gh\").args([\"auth\", \"status\"]).output()?;\nif !auth.status.success() {\n    return Err(anyhow!(\"gh not authenticated; run `gh auth login`\"));\n}","typeGuard":null,"tryCatchPattern":"let msg = e.to_string();\nif msg.contains(\"gh auth\") || msg.contains(\"authentication\") {\n    eprintln!(\"run `gh auth login` or set GH_TOKEN\");\n} else if msg.contains(\"rate limit\") {\n    eprintln!(\"wait for rate-limit reset or use a token with higher limits\");\n}\nreturn Err(e);","preventionTips":["Keep gh authenticated: check `gh auth status` in setup scripts","Set GH_TOKEN in CI rather than interactive login","Verify network/proxy access to api.github.com","Run the failing gh command manually to read its full stderr"],"tags":["github","gh-cli","process-exit","network","auth"],"backgroundTag":"gh-cli-command-failed","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}