affaan-m/ECC · error · Error

${displayCommand} failed: ${(result.stderr || result.stdout

Error message

${displayCommand} failed: ${(result.stderr || result.stdout || '').trim()}

What it means

Thrown by scripts/runGhJson in scripts/work-items.js when spawnSync succeeds (gh ran) but exits with a non-zero status. The trimmed stderr (or stdout if no stderr) is appended to the display command so the underlying GitHub CLI failure is visible. Common root causes are authentication failure, a nonexistent or private repo, rate limiting, or a network error reaching GitHub.

Source

Thrown at scripts/work-items.js:160

  return parsed;
}

function runGhJson(args) {
  const shimPath = process.env.ECC_GH_SHIM;
  const command = shimPath ? process.execPath : 'gh';
  const commandArgs = shimPath ? [shimPath, ...args] : args;
  const displayCommand = shimPath ? `node ${shimPath} ${args.join(' ')}` : `gh ${args.join(' ')}`;
  const result = spawnSync(command, commandArgs, {
    encoding: 'utf8',
    maxBuffer: 10 * 1024 * 1024
  });

  if (result.error) {
    throw new Error(`Failed to run gh: ${result.error.message}`);
  }

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

  try {
    return JSON.parse(result.stdout || '[]');
  } catch (error) {
    throw new Error(`${displayCommand} returned invalid JSON: ${error.message}`);
  }
}

function slugifyWorkItemSegment(value) {
  return (
    String(value || '')
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, '-')
      .replace(/^-+|-+$/g, '') || 'unknown'
  );
}

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Run `gh auth status` and, if logged out, `gh auth login` with a token that has repo read scope.
  2. Verify the --repo value is `owner/repo` and that the repo exists and is accessible to the authenticated user.
  3. If rate-limited, wait and retry, or authenticate to raise the limit ceiling.
  4. Read the trimmed stderr in the error message — it carries the exact GitHub CLI reason.

Example fix

// before
node scripts/work-items.js sync-github --repo owner/nonexistent
# Error: gh pr list ... failed: HTTP 404: Not Found

// after
gh auth login
node scripts/work-items.js sync-github --repo owner/existing-repo
Defensive patterns

Strategy: retry

Validate before calling

const { spawnSync } = require('child_process');
function ghAuthed() {
  const r = spawnSync('gh', ['auth', 'status'], { encoding: 'utf8' });
  return r.status === 0;
}
function ghRepoReadable(repo) {
  const r = spawnSync('gh', ['repo', 'view', repo], { encoding: 'utf8' });
  return r.status === 0;
}
if (!ghAuthed()) throw new Error('Run `gh auth login` before sync-github');
if (!ghRepoReadable('owner/repo')) throw new Error('Repo not accessible to current gh auth');

Try / catch

// Retry transient gh failures (rate limit, network) with backoff
async function syncWithRetry(repo, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return runSync(['sync-github', '--repo', repo]);
    } catch (e) {
      const transient = /rate limit|HTTP 5\d\d|failed:/i.test(e.message);
      if (!transient || i === maxRetries - 1) throw e;
      await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i)));
    }
  }
}

Prevention

When it happens

Trigger: `sync-github --repo owner/nonexistent`; gh not authenticated (`gh auth status` shows logged out); GitHub API rate limit exceeded; transient network failure during the `gh pr list` / `gh issue list` calls.

Common situations: Running sync-github before `gh auth login`; a repo typed as `repo` instead of `owner/repo`; CI token expired or lacks read scope on the target repo; shared CI runner hitting the unauthenticated rate limit.

Related errors


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