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
- Read the embedded stderr to find the exact gh error (auth, not-found, rate-limit, forbidden).
- Authenticate gh: run `gh auth login` or export GH_TOKEN with adequate scopes (repo, read:org).
- For transient errors (rate limit, 5xx), retry with backoff.
- 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
- Authenticate gh and set GH_TOKEN with adequate scopes in CI.
- Retry with backoff on transient (rate-limit/5xx) stderr messages.
- Parse the embedded stderr to map auth/not-found/forbidden to fixes.
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
- ${command} ${args.join(' ')} failed: ${result.error.message}
- Unable to load issue #${issueNumber} from ${repo}
- Invalid repo format: "${repo}". Expected "owner/repo".
- Invalid issue number: ${value}
- gh ${args.join(' ')} returned invalid JSON: ${error.message}
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/c54aae4c93c65197.
Report an issue: GitHub.