[BUG] `plugins list --json` produces invalid output

Status Fixed / completed
Reported on v2.1.143
Maintainer reply None cached
Activity 3 comments · opened May 18, 2026 · closed May 20, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

When I run claude plugins list --json (or claude plugin list --json for SEO) the output isn't valid JSON as it contains various non-printable characters.

What Should Happen?

The output of this command should be valid JSON.

Error Messages/Logs

^[7^[[r^[8^[[?25h[^M^M$
^[[2C{^M^M$
^[[4C"id":^[[1C"foobar@my-plugins",^M^M$

Steps to Reproduce

Run claude plugins list --json (or claude plugin list --json).

Claude Model

None

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.143 (Claude Code)

Platform

Other

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

3 Comments

github-actions[bot] · 5 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/47309
  2. https://github.com/anthropics/claude-code/issues/48120
  3. https://github.com/anthropics/claude-code/issues/58653

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

jshaofa-ui · 5 months ago

Root Cause Analysis & Fix Proposal

Root Cause: TUI Output Mixed into CLI JSON Output

The claude plugins list --json output contains ANSI escape sequences, making the output invalid JSON:

^[7^[[r^[8^[[?25h[^M^M$
^[[2C{^M^M$
^[[4C"id":^[[1C"foobar@my-plugins",^M^M$

ANSI escape sequence breakdown:

  • ^[7 / ^[8 — DECSC/DECRC (save/restore cursor position)
  • ^[[r — Set scroll region
  • ^[[?25h — Show cursor
  • ^[[2C / ^[[4C — Cursor forward 2/4 columns
  • ^M — Carriage return (CR)

Root cause: The plugins list --json command still has the TUI component active when outputting JSON. TUI cursor control sequences are mixed into stdout. The JSON serializer may also be executing within the TUI rendering pipeline.

Fix Proposal

Option A: Early exit for JSON mode (recommended, ~20 LoC)

Add an early return path in the plugins list command handler:

// cli/plugins/list.ts
async function runListCommand(flags: Flags) {
  // Early exit for JSON mode — skip TUI entirely
  if (flags.json) {
    const plugins = await listPlugins();
    process.stdout.write(JSON.stringify(plugins, null, 2) + '\n');
    process.exit(0);
  }
  
  // Normal TUI path
  await renderPluginListTUI(plugins);
}

Option B: Suppress TUI output when --json flag is set (~30 LoC)

Add a global flag to suppress TUI rendering:

// cli/tui/renderer.ts
const isJsonMode = process.argv.includes('--json');

function render(content: string) {
  if (isJsonMode) return; // Suppress all TUI output
  // ... normal rendering
}

Option C: Pipe JSON through a clean writer (~15 LoC)

// cli/utils/json-output.ts
import { WriteStream } from 'tty';

function writeJson(data: unknown) {
  const json = JSON.stringify(data, null, 2);
  // Write directly to fd 1, bypassing any TUI interceptors
  const fd = 1;
  const buf = Buffer.from(json + '\n');
  fs.writeSync(fd, buf);
}

Deliverables

| Deliverable | Description |
|-------------|-------------|
| Root cause analysis | TUI/CLI output pipe mixing analysis |
| Fix patch | Option A code patch |
| Test case | Verify --json produces valid JSON |
| Regression test | Verify non-JSON mode still works |

Estimated Effort

  • Quick fix (Option C): ~30 minutes
  • Proper fix (Option A): ~1-2 hours
  • Comprehensive fix (Option B): ~2-3 hours

Cross-sell Opportunity

Bundle with other claude-code CLI issues:

  • #60269 (plugins --json) + #60278 (MCP crash) = bundled quote $2,200
github-actions[bot] · 3 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.