can1357/oh-my-pi · error · ToolError
GitHub CLI returned invalid JSON output.
Error message
GitHub CLI returned invalid JSON output.
What it means
github.json<T>() runs the `gh` CLI and parses stdout as JSON. If `gh` exits 0 but its stdout is not parseable JSON, the wrapper converts JSON.parse's failure into a ToolError so callers get a clear message instead of a SyntaxError.
Source
Thrown at packages/coding-agent/src/utils/github.ts:131
stdout: trim ? stdout.trim() : stdout,
stderr: trim ? stderr.trim() : stderr,
};
} catch (error) {
if (signal?.aborted) throw new ToolAbortError();
if (timeoutSignal.aborted) throw new ToolError(`GitHub CLI command timed out: gh ${args.join(" ")}`);
throw error;
}
},
/** Run `gh` and parse stdout as JSON. Throws on non-zero exit or invalid JSON. */
async json<T>(cwd: string, args: string[], signal?: AbortSignal, options?: GhCommandOptions): Promise<T> {
const result = await github.run(cwd, args, signal, options);
if (result.exitCode !== 0) throw new ToolError(formatGhFailure(args, result.stdout, result.stderr, options));
if (!result.stdout) throw new ToolError("GitHub CLI returned empty output.");
try {
return JSON.parse(result.stdout) as T;
} catch {
throw new ToolError("GitHub CLI returned invalid JSON output.");
}
},
/** Run `gh` and return stdout as text. Throws on non-zero exit. */
async text(cwd: string, args: string[], signal?: AbortSignal, options?: GhCommandOptions): Promise<string> {
const result = await github.run(cwd, args, signal, options);
if (result.exitCode !== 0) throw new ToolError(formatGhFailure(args, result.stdout, result.stderr, options));
return result.stdout;
},
};
View on GitHub (pinned to 9690622007)
Solutions
- Add the --json flag with required fields to the gh args (e.g. pr list --json number,title).
- Run the same command manually with gh ... and inspect what non-JSON text is emitted on stdout.
- Check the gh version (gh --version) and upgrade if it does not support the requested --json fields.
- Use github.text() instead if the endpoint legitimately returns plain text.
- Remove wrappers/aliases around gh that inject extra output into stdout.
Example fix
// before: await github.json(cwd, ["pr", "list", "--limit", "5"]); // after: await github.json(cwd, ["pr", "list", "--limit", "5", "--json", "number,title,state"]);
Defensive patterns
Strategy: try-catch
Validate before calling
const args = ["pr", "list", "--json", "number,title"]; if (!args.includes("--json")) throw new Error("github.json() requires --json in args"); Type guard
function isJsonObject(v: unknown): v is Record<string, unknown> { return typeof v === "object" && v !== null && !Array.isArray(v); } // narrow the parsed value after JSON.parse Try / catch
try { const data = await github.json<MyType>(cwd, args); } catch (err) { if (err instanceof ToolError && /invalid JSON/.test(err.message)) { const raw = await github.text(cwd, args); /* inspect raw output or fall back */ } else { throw err; } } Prevention
- Always pass --json with explicit fields when using github.json().
- Pin/verify the gh version supports the requested JSON fields.
- Avoid shell wrappers or aliases around gh that emit extra stdout.
- Sanity-check raw output with `gh ... | jq .` during development.
When it happens
Trigger: Calling github.json() with args whose output is not JSON: missing --json flag (e.g. `gh pr list` without --json), gh emitting warnings or progress text on stdout, an aliased or wrapped gh producing human output, or a non-JSON output format (--template).
Common situations: Constructing gh args by hand and forgetting --json <fields>; older gh versions lacking a JSON field; gh printing notices alongside data; shell wrappers that prefix output.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid record JSON: ${rawValue}
- `omp gallery --screenshot` requires VHS, which is not instal
- VHS failed to render the gallery screenshot${detail ? `: ${d
- --list-details, --exec, and --exec-batch are not supported b
- positional paths cannot be combined with --search-path
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/ea6007cbe40175a6.
Report an issue: GitHub.