thedotmack/claude-mem · error · Error
Could not parse ${label} JSON: ${message}
Error message
Could not parse ${label} JSON: ${message} What it means
Thrown by parseJson() when JSON.parse fails on output returned by runGh(). It labels which logical payload failed ('pull request', 'checks', 'reviews', etc.) so the caller knows which gh call produced unparseable text. This guards every JSON-expecting gh result in the script.
Source
Thrown at scripts/pr-babysit-status.ts:124
}
}
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.');
}
const ghVersion = runCommand(['gh', '--version']);
if (ghVersion.exitCode !== 0) {
throw new Error('GitHub CLI is not available. Install gh and try again.');
}
const auth = runCommand(['gh', 'auth', 'status']);
if (auth.exitCode !== 0) {
throw new Error(`GitHub CLI is not authenticated. Run "gh auth login".\n${auth.stderr || auth.stdout}`.trim());
}View on GitHub (pinned to d768ba3643)
Solutions
- Reproduce by running the exact gh command (shown via the label and the failing call site) and inspect its raw stdout.
- Suppress gh noise: ensure GH_NO_UPDATE_NOTIFIER or run with a quiet/known gh version.
- If stdout is empty, guard parseJson callers to skip when raw is falsy (the checks path already does `raw ? parseJson(...) : []`).
- If pagination is the cause, switch from --paginate to an explicit loop with a per-page parse.
Example fix
// before — always parse even when gh printed nothing
return parseJson<CheckRun[]>(runGh([...]), 'checks')
// after — skip parse on empty output
const raw = runGh([...], { allowExitCodes: [GH_PENDING_EXIT_CODE] })
return raw ? parseJson<CheckRun[]>(raw, 'checks') : [] Defensive patterns
Strategy: validation
Validate before calling
function tryParse<T>(raw: string, label: string): T | null {
try { return JSON.parse(raw) as T; } catch { return null; }
}
// skip when raw is empty
const data = raw ? tryJson<T>(raw, 'checks') : []; Type guard
function looksLikeJson(s: string): boolean {
const t = s.trim();
return t.startsWith('{') || t.startsWith('[');
} Try / catch
try {
return parseJson<T>(raw, label);
} catch (e) {
if (e instanceof Error && /Could not parse/.test(e.message)) {
console.error(`gh produced non-JSON for ${label}:`, raw.slice(0, 200));
}
throw e;
} Prevention
- Suppress gh update banners and noise that can leak into stdout (GH_NO_UPDATE_NOTIFIER).
- Guard parseJson callers to skip parsing when stdout is empty.
- Pin a known gh version in CI so output shape is stable.
When it happens
Trigger: gh emitted a non-JSON string before its JSON (e.g. a warning on stderr merged into stdout, a deprecation notice, an interactive prompt). An empty stdout where parseJson was still called. A gh version that changes the --json shape. A network glitch truncating paginated output mid-array.
Common situations: gh updated to a version that prepends a banner. gh api --paginate interleaving records in a way that isn't a clean JSON array. Running in an environment where gh prints update notifications to stdout. A repo so large that paginated reviews exceed memory and produce partial output.
Related errors
- gh ${args.join(' ')} failed: ${detail}
- GitHub CLI is not available. Install gh and try again.
- GitHub CLI is not authenticated. Run "gh auth login". ${auth
- strip introduced ${afterErrs - beforeErrs} new parse error(s
- Corrupt JSON in ${GEMINI_SETTINGS_PATH}, refusing to overwri
AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12).
Data as JSON: /api/errors/4a3d60da40a9847a.
Report an issue: GitHub.