{"record":{"id":"27c7efc9fbe36990","repo":"affaan-m/ECC","slug":"displaycommand-returned-invalid-json-error-m","errorCode":null,"errorMessage":"${displayCommand} returned invalid JSON: ${error.message}","messagePattern":"(.+?) returned invalid JSON: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/work-items.js","lineNumber":166,"sourceCode":"  const commandArgs = shimPath ? [shimPath, ...args] : args;\n  const displayCommand = shimPath ? `node ${shimPath} ${args.join(' ')}` : `gh ${args.join(' ')}`;\n  const result = spawnSync(command, commandArgs, {\n    encoding: 'utf8',\n    maxBuffer: 10 * 1024 * 1024\n  });\n\n  if (result.error) {\n    throw new Error(`Failed to run gh: ${result.error.message}`);\n  }\n\n  if (result.status !== 0) {\n    throw new Error(`${displayCommand} failed: ${(result.stderr || result.stdout || '').trim()}`);\n  }\n\n  try {\n    return JSON.parse(result.stdout || '[]');\n  } catch (error) {\n    throw new Error(`${displayCommand} returned invalid JSON: ${error.message}`);\n  }\n}\n\nfunction slugifyWorkItemSegment(value) {\n  return (\n    String(value || '')\n      .toLowerCase()\n      .replace(/[^a-z0-9]+/g, '-')\n      .replace(/^-+|-+$/g, '') || 'unknown'\n  );\n}\n\nfunction githubWorkItemId(repo, type, number) {\n  return `github-${slugifyWorkItemSegment(repo)}-${type}-${number}`;\n}\n\nfunction githubPrStatus(pr) {\n  if (pr.isDraft || pr.mergeStateStatus === 'DIRTY') {","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/work-items.js#L148-L184","documentation":"Thrown by scripts/runGhJson in scripts/work-items.js when gh exits 0 but its stdout cannot be parsed as JSON (JSON.parse throws). The function explicitly requests JSON output via `--json ...` flags, so valid JSON is expected; a parse failure indicates gh produced unexpected text — most often because a gh extension, alias, or shell wrapper intercepted the command and emitted human-readable or prefixed output instead of raw JSON.","triggerScenarios":"A gh extension or alias shadowing `pr list` / `issue list` that prints a header line before the JSON; a gh version that changes field names or output shape; stdout contaminated by a shell rc file or a gh plugin banner; ECC_GH_SHIM returning non-JSON output.","commonSituations":"Users with gh extensions installed that modify default output; a custom gh wrapper script set via ECC_GH_SHIM that does not emit clean JSON; a gh version downgrade/upgrade that altered the JSON schema.","solutions":["Run the underlying gh command manually (`gh pr list --repo owner/repo --json number,title,...`) and inspect stdout to see what non-JSON content is present.","Disable or bypass gh aliases/extensions that alter list output (check `gh alias list` and installed extensions).","If using ECC_GH_SHIM, ensure the shim prints only the JSON array to stdout (send any logging to stderr).","Confirm the gh version supports the requested --json fields."],"exampleFix":"// before\n# gh alias 'pr' prepends a banner line, breaking JSON.parse\nnode scripts/work-items.js sync-github --repo owner/repo\n\n// after\ngh alias delete pr\nnode scripts/work-items.js sync-github --repo owner/repo","handlingStrategy":"validation","validationCode":"const { spawnSync } = require('child_process');\nfunction ghEmitsCleanJson(repo) {\n  const r = spawnSync('gh', ['pr', 'list', '--repo', repo, '--state', 'open', '--limit', '1', '--json', 'number'], { encoding: 'utf8' });\n  if (r.status !== 0) return false;\n  try { JSON.parse(r.stdout); return true; } catch { return false; }\n}\nif (!ghEmitsCleanJson('owner/repo')) {\n  throw new Error('gh is not emitting clean JSON — check aliases/extensions (gh alias list)');\n}","typeGuard":"function isJsonArray(stdout) {\n  try { const v = JSON.parse(stdout); return Array.isArray(v); } catch { return false; }\n}","tryCatchPattern":"// When invalid JSON is seen, fall back to a direct GitHub API call or skip the sync\ntry {\n  runSync(['sync-github', '--repo', repo]);\n} catch (e) {\n  if (/invalid JSON/.test(e.message)) {\n    console.warn('gh produced non-JSON output; check gh aliases/extensions. Skipping sync.');\n  } else {\n    throw e;\n  }\n}","preventionTips":["Periodically run `gh alias list` and `gh extension list` to spot output-modifying add-ons.","If using ECC_GH_SHIM, ensure it writes only JSON to stdout and logs to stderr.","Pin the gh version in CI so the JSON schema does not change unexpectedly.","Smoke-test `gh pr list --json number` output parses before relying on sync-github."],"tags":["cli","github","json","external-dependency","gh-extension","work-items"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}