{"record":{"id":"ecdc6400327b62bb","repo":"thedotmack/claude-mem","slug":"gh-args-join-failed-detail","errorCode":null,"errorMessage":"gh ${args.join(' ')} failed: ${detail}","messagePattern":"gh (.+?) failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/pr-babysit-status.ts","lineNumber":114,"sourceCode":"    });\n\n    return {\n      stdout: new TextDecoder().decode(result.stdout).trim(),\n      stderr: new TextDecoder().decode(result.stderr).trim(),\n      exitCode: result.exitCode,\n    };\n  } catch (error) {\n    const message = error instanceof Error ? error.message : String(error);\n    return { stdout: '', stderr: message, exitCode: 127 };\n  }\n}\n\nfunction runGh(args: string[], options: { allowExitCodes?: number[] } = {}): string {\n  const result = runCommand(['gh', ...args]);\n  const allowed = new Set([0, ...(options.allowExitCodes ?? [])]);\n  if (!allowed.has(result.exitCode)) {\n    const detail = result.stderr || result.stdout || `exit code ${result.exitCode}`;\n    throw new Error(`gh ${args.join(' ')} failed: ${detail}`);\n  }\n  return result.stdout;\n}\n\nfunction parseJson<T>(raw: string, label: string): T {\n  try {\n    return JSON.parse(raw) as T;\n  } catch (error) {\n    const message = error instanceof Error ? error.message : String(error);\n    throw new Error(`Could not parse ${label} JSON: ${message}`);\n  }\n}\n\nfunction checkPrerequisites() {\n  const git = runCommand(['git', 'rev-parse', '--is-inside-work-tree']);\n  if (git.exitCode !== 0 || git.stdout.trim() !== 'true') {\n    throw new Error('Not in a git repository. Run this from a checked-out repo.');\n  }","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/scripts/pr-babysit-status.ts#L96-L132","documentation":"Thrown by runGh() when a `gh` invocation exits with a code not in the allowed set (default only 0; callers can pass allowExitCodes). It surfaces the failing gh command line plus the stderr/stdout detail so the caller can see why gh itself objected. This is the single chokepoint for every gh call in pr-babysit-status.","triggerScenarios":"gh pr view with a PR number that does not exist (exit 1). gh pr checks returning a hard error rather than the expected pending code 8. gh api hitting a rate limit (exit 1 with a 403 body). gh repo view outside a repo. Network failure to api.github.com. Insufficient token scopes for a protected endpoint.","commonSituations":"Running the script against a PR number from a fork the token can't read. A GITHUB_TOKEN with read-only scopes hitting a write endpoint. GitHub secondary rate limits. A typo'd PR number. gh configured against the wrong enterprise host.","solutions":["Read the detail in the error (it is gh's own stderr) and address that primary cause first.","If it is a rate limit, wait and retry; for secondary limits, reduce the number of gh api --paginate calls.","Verify the PR number/branch argument is correct and accessible to the authenticated user.","Run `gh auth status` to confirm token scopes; broaden scopes or re-login if the endpoint requires more.","Pass allowExitCodes where a non-zero code is expected semantics (e.g. 8 for pending checks) rather than treating it as failure."],"exampleFix":"// before — pending checks (gh exit 8) treated as failure\nrunGh(['pr', 'checks', '--json', fields])\n// after — exit 8 is a valid 'pending' signal\nrunGh(['pr', 'checks', '--json', fields], { allowExitCodes: [GH_PENDING_EXIT_CODE] })","handlingStrategy":"try-catch","validationCode":"const gh = runCommand(['gh', '--version']);\nif (gh.exitCode !== 0) throw new Error('gh unavailable');","typeGuard":null,"tryCatchPattern":"try {\n  return runGh(['pr', 'view', '--json', fields]);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('gh pr view')) {\n    // PR not found / no permission -> prompt for correct PR number\n  }\n  throw e;\n}","preventionTips":["Call checkPrerequisites() once up front so missing gh/auth fails loudly before any runGh.","Pass allowExitCodes for gh exit codes that carry semantic meaning (e.g. 8 for pending checks).","Keep gh api calls paginated and bounded to avoid rate-limit failures."],"tags":["github","cli","gh","process"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}