affaan-m/ECC · error · Error

${command} ${args.join(' ')} failed: ${(result.stderr || res

Error message

${command} ${args.join(' ')} failed: ${(result.stderr || result.stdout || '').trim()}

What it means

Thrown by runCommand when the child process spawned successfully but exited with a non-zero status. The message includes the trimmed stderr (falling back to stdout) so the caller sees gh's own error output. Common causes are auth failures, rate limits, missing resources, or invalid gh arguments.

Source

Thrown at scripts/lib/github-coordination/gh-api.js:49

function normalizeLabels(labels) {
  return Array.from(new Set((Array.isArray(labels) ? labels : []).map(normalizeLabelValue).filter(Boolean))).sort();
}

function runCommand(command, args, options = {}) {
  const result = spawnSync(command, args, {
    cwd: options.cwd,
    env: options.env || process.env,
    encoding: 'utf8',
    maxBuffer: 10 * 1024 * 1024,
  });

  if (result.error) {
    throw new Error(`${command} ${args.join(' ')} failed: ${result.error.message}`);
  }

  if (result.status !== 0) {
    throw new Error(`${command} ${args.join(' ')} failed: ${(result.stderr || result.stdout || '').trim()}`);
  }

  return result.stdout || '';
}

// ECC_GH_SHIM creates a trust boundary: when set, shimPath replaces the real
// `gh` binary and command/commandArgs execute an arbitrary script via
// process.execPath. This variable MUST only be set in trusted, isolated test
// environments (e.g., a test's own temp directory). Never set ECC_GH_SHIM in
// production — doing so allows arbitrary script execution under the caller's
// privileges.
function runGh(args, options = {}) {
  const shimPath = process.env.ECC_GH_SHIM;
  const command = shimPath ? process.execPath : 'gh';
  const commandArgs = shimPath ? [shimPath, ...args] : args;
  const env = { ...process.env };

  if (options.stripGithubToken) {

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Read the embedded stderr to find the exact gh error (auth, not-found, rate-limit, forbidden).
  2. Authenticate gh: run `gh auth login` or export GH_TOKEN with adequate scopes (repo, read:org).
  3. For transient errors (rate limit, 5xx), retry with backoff.
  4. Verify the repo/issue exists and the token can access it; fix any invalid gh flags.

Example fix

// before
runGh(['issue', 'view', String(n), '--repo', repo]);

// after — capture and rethrow with actionable context
try {
  runGh(['issue', 'view', String(n), '--repo', repo]);
} catch (e) {
  if (/auth/i.test(e.message)) throw new Error('gh auth failed: run `gh auth login` or set GH_TOKEN');
  if (/rate limit/i.test(e.message)) { await sleep(60000); throw e; }
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

const { spawnSync } = require('child_process');
const auth = spawnSync('gh', ['auth', 'status'], { encoding: 'utf8' });
if (auth.status !== 0) {
  throw new Error('gh not authenticated: run `gh auth login` or set GH_TOKEN');
}

Type guard

function ghAuthenticated() {
  return spawnSync('gh', ['auth', 'status'], { encoding: 'utf8' }).status === 0;
}

Try / catch

async function ghWithRetry(fn, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try { return fn(); }
    catch (e) {
      if (/rate limit/i.test(e.message) && i < retries - 1) { await new Promise(r => setTimeout(r, 60000 * (i + 1))); continue; }
      throw e;
    }
  }
}

Prevention

When it happens

Trigger: gh is not authenticated (gh auth status fails); the issue/repo does not exist; rate limited by the API; invalid gh flags; network failure mid-call; permissions/forbidden.

Common situations: CI without GH_TOKEN set; token expired or lacks scope; referencing a private repo the token can't read; gh version mismatch changing flag semantics; transient API errors.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/c54aae4c93c65197. Report an issue: GitHub.