thedotmack/claude-mem · error · Error

gh ${args.join(' ')} failed: ${detail}

Error message

gh ${args.join(' ')} failed: ${detail}

What it means

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.

Source

Thrown at scripts/pr-babysit-status.ts:114

    });

    return {
      stdout: new TextDecoder().decode(result.stdout).trim(),
      stderr: new TextDecoder().decode(result.stderr).trim(),
      exitCode: result.exitCode,
    };
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    return { stdout: '', stderr: message, exitCode: 127 };
  }
}

function runGh(args: string[], options: { allowExitCodes?: number[] } = {}): string {
  const result = runCommand(['gh', ...args]);
  const allowed = new Set([0, ...(options.allowExitCodes ?? [])]);
  if (!allowed.has(result.exitCode)) {
    const detail = result.stderr || result.stdout || `exit code ${result.exitCode}`;
    throw new Error(`gh ${args.join(' ')} failed: ${detail}`);
  }
  return result.stdout;
}

function parseJson<T>(raw: string, label: string): T {
  try {
    return JSON.parse(raw) as T;
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    throw new Error(`Could not parse ${label} JSON: ${message}`);
  }
}

function checkPrerequisites() {
  const git = runCommand(['git', 'rev-parse', '--is-inside-work-tree']);
  if (git.exitCode !== 0 || git.stdout.trim() !== 'true') {
    throw new Error('Not in a git repository. Run this from a checked-out repo.');
  }

View on GitHub (pinned to d768ba3643)

Solutions

  1. Read the detail in the error (it is gh's own stderr) and address that primary cause first.
  2. If it is a rate limit, wait and retry; for secondary limits, reduce the number of gh api --paginate calls.
  3. Verify the PR number/branch argument is correct and accessible to the authenticated user.
  4. Run `gh auth status` to confirm token scopes; broaden scopes or re-login if the endpoint requires more.
  5. Pass allowExitCodes where a non-zero code is expected semantics (e.g. 8 for pending checks) rather than treating it as failure.

Example fix

// before — pending checks (gh exit 8) treated as failure
runGh(['pr', 'checks', '--json', fields])
// after — exit 8 is a valid 'pending' signal
runGh(['pr', 'checks', '--json', fields], { allowExitCodes: [GH_PENDING_EXIT_CODE] })
Defensive patterns

Strategy: try-catch

Validate before calling

const gh = runCommand(['gh', '--version']);
if (gh.exitCode !== 0) throw new Error('gh unavailable');

Try / catch

try {
  return runGh(['pr', 'view', '--json', fields]);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('gh pr view')) {
    // PR not found / no permission -> prompt for correct PR number
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12). Data as JSON: /api/errors/ecdc6400327b62bb. Report an issue: GitHub.