{"record":{"id":"079071d2abb46482","repo":"EveryInc/compound-engineering-plugin","slug":"label-returned-invalid-json-error-instanceof","errorCode":null,"errorMessage":"${label} returned invalid JSON: ${error instanceof Error ? error.message : String(error)}","messagePattern":"(.+?) returned invalid JSON: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/dev/codex-dev.ts","lineNumber":438,"sourceCode":"  if (state.kind === \"absent\") return false\n  if (state.kind === \"collision\") {\n    throw new Error(`${context.collectionPath} exists and is not a symlink; refusing to remove it`)\n  }\n  if (state.kind === \"unrelated\") {\n    throw new Error(`${context.collectionPath} points outside a Compound Engineering checkout; refusing to remove it`)\n  }\n  if (state.kind === \"broken\") {\n    throw new Error(`${context.collectionPath} is a broken symlink; refusing to remove it automatically`)\n  }\n  await removeManagedCollectionLink(context.collectionPath, state.target)\n  return true\n}\n\nfunction parseJson<T>(result: CommandResult, label: string): T {\n  try {\n    return JSON.parse(result.stdout) as T\n  } catch (error) {\n    throw new Error(`${label} returned invalid JSON: ${error instanceof Error ? error.message : String(error)}`)\n  }\n}\n\nasync function runCodex(\n  context: CodexDevContext,\n  runner: CommandRunner,\n  args: string[],\n): Promise<CommandResult> {\n  return checkedRun(runner, \"codex\", args, { cwd: context.repoRoot, env: context.env })\n}\n\nasync function listCompoundEngineeringPlugins(\n  context: CodexDevContext,\n  runner: CommandRunner,\n): Promise<InstalledPlugin[]> {\n  const result = await runCodex(context, runner, [\"plugin\", \"list\", \"--available\", \"--json\"])\n  const payload = parseJson<{ installed?: InstalledPlugin[] }>(result, \"codex plugin list\")\n  return (payload.installed ?? []).filter(","sourceCodeStart":420,"sourceCodeEnd":456,"githubUrl":"https://github.com/EveryInc/compound-engineering-plugin/blob/c9c10f8c75412c7232cb2bd663e5fd1cea98d84e/src/dev/codex-dev.ts#L420-L456","documentation":"parseJson() wraps JSON.parse of a Codex CLI command's stdout and re-raises a labeled error when the output is not valid JSON. Every consumer of `codex ... --json` output (payload(), listMarketplaces()) funnels through here so callers get a clear message instead of a raw SyntaxError.","triggerScenarios":"Running a `codex` subcommand whose stdout is not parseable JSON — the CLI printed a warning/banner before the JSON, emitted human-readable output on stdout, crashed mid-print, or an unexpected codex version changed the output format.","commonSituations":"Outdated or prerelease codex CLI producing non-JSON output; codex writing update notices or prompts into stdout; codex not actually supporting the invoked --json flag; shell wrapper functions aliasing `codex` to something else.","solutions":["Run the same `codex ...` command by hand and inspect its raw stdout","Update or pin the codex CLI (`codex --version`, install a stable release) to match expected JSON output","Check that stdout is clean JSON — redirect stderr separately and remove shell banners/aliases","Upgrade the compound-engineering CLI if the codex output format legitimately changed"],"exampleFix":"// before\n$ bun run codex:dev -- status\n// Error: codex plugin list returned invalid JSON: Unexpected token 'n' ...\n\n// after\n$ codex --version && codex plugin list   # see raw output\n$ npm i -g @openai/codex@latest           # update CLI\n$ bun run codex:dev -- status","handlingStrategy":"try-catch","validationCode":"const out = await runCodex(context, runner, args);\nif (out.exitCode !== 0 || !out.stdout.trim().startsWith(\"{\")) {\n  throw new Error(`codex output not JSON: ${out.stdout.slice(0, 200)}`);\n}","typeGuard":"function isJsonObject(v: unknown): v is Record<string, unknown> {\n  return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  const plugins = await listMarketplaces(context, runner);\n} catch (e) {\n  if (String(e).includes(\"returned invalid JSON\")) {\n    console.error(\"codex CLI output unexpected — check `codex --version` and stdout for banners\");\n  } else throw e;\n}","preventionTips":["Pin a stable codex CLI version and update deliberately","Do not wrap `codex` in shell functions that print to stdout","Check stderr vs stdout separation when debugging CLI output"],"tags":["json","parsing","cli","codex-dev"],"backgroundTag":"invalid-json-output","analyzedSha":"c9c10f8c75412c7232cb2bd663e5fd1cea98d84e","analyzedAt":"2026-08-31T15:18:07.959Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}