{"record":{"id":"ea6007cbe40175a6","repo":"can1357/oh-my-pi","slug":"github-cli-returned-invalid-json-output","errorCode":null,"errorMessage":"GitHub CLI returned invalid JSON output.","messagePattern":"GitHub CLI returned invalid JSON output\\.","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/utils/github.ts","lineNumber":131,"sourceCode":"\t\t\t\tstdout: trim ? stdout.trim() : stdout,\n\t\t\t\tstderr: trim ? stderr.trim() : stderr,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (signal?.aborted) throw new ToolAbortError();\n\t\t\tif (timeoutSignal.aborted) throw new ToolError(`GitHub CLI command timed out: gh ${args.join(\" \")}`);\n\t\t\tthrow error;\n\t\t}\n\t},\n\n\t/** Run `gh` and parse stdout as JSON. Throws on non-zero exit or invalid JSON. */\n\tasync json<T>(cwd: string, args: string[], signal?: AbortSignal, options?: GhCommandOptions): Promise<T> {\n\t\tconst result = await github.run(cwd, args, signal, options);\n\t\tif (result.exitCode !== 0) throw new ToolError(formatGhFailure(args, result.stdout, result.stderr, options));\n\t\tif (!result.stdout) throw new ToolError(\"GitHub CLI returned empty output.\");\n\t\ttry {\n\t\t\treturn JSON.parse(result.stdout) as T;\n\t\t} catch {\n\t\t\tthrow new ToolError(\"GitHub CLI returned invalid JSON output.\");\n\t\t}\n\t},\n\n\t/** Run `gh` and return stdout as text. Throws on non-zero exit. */\n\tasync text(cwd: string, args: string[], signal?: AbortSignal, options?: GhCommandOptions): Promise<string> {\n\t\tconst result = await github.run(cwd, args, signal, options);\n\t\tif (result.exitCode !== 0) throw new ToolError(formatGhFailure(args, result.stdout, result.stderr, options));\n\t\treturn result.stdout;\n\t},\n};\n","sourceCodeStart":113,"sourceCodeEnd":142,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/utils/github.ts#L113-L142","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before: await github.json(cwd, [\"pr\", \"list\", \"--limit\", \"5\"]);  // after: await github.json(cwd, [\"pr\", \"list\", \"--limit\", \"5\", \"--json\", \"number,title,state\"]);","handlingStrategy":"try-catch","validationCode":"const args = [\"pr\", \"list\", \"--json\", \"number,title\"]; if (!args.includes(\"--json\")) throw new Error(\"github.json() requires --json in args\");","typeGuard":"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","tryCatchPattern":"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; } }","preventionTips":["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."],"tags":["cli","json-parsing","external-tool"],"backgroundTag":"invalid-json-output","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}