Skip to main content
← Back to list
01Issue
BugClosedSwamp CLIPublic
Assigneeshammz

Relationships

#2524 swamp xxx xxxx --json: cursor-visibility ANSI escapes leak to stdout, corrupting JSON output

Opened by shelson · 9/25/2026

Description

swamp xxx xxxx --json output contains invisible cursor-visibility ANSI escape sequences that corrupt the JSON stream. When piped to jq, the result is:

    }
  ]
}
jq: parse error: Invalid numeric literal at line 4232, column 2

The raw bytes seen are \033[?12l\033[?25h — these are:

  • \033[?12l — DEC private mode: stop cursor blinking
  • \033[?25h — DECTCEM: show cursor

These are terminal control codes, not colour codes. They look like TUI library (Bubble Tea / similar) init/restore sequences leaking to stdout even in --json mode. They are invisible to the eye but break machine parsing.

Steps to Reproduce

  1. Run any swamp xxx xxxx --json command (occurs in agent-harness environments)
  2. Pipe to jq or cat -v
  3. Observe cursor control escapes interleaved with JSON output
  • #430 — --json output is polluted by non-JSON content (shipped)
  • #2414 — swamp --version emits ANSI escapes when piped (shipped)
  • #1866 — --server list commands render TUI picker into non-TTY pipe (shipped)

These cursor-visibility sequences are a new variant of the same class — not colour ANSI but terminal control codes — and appear to come from a different source than the prior fixes addressed.

02Bog Flow
✓OPEN○TRIAGED○IN PROGRESS◉CLOSED+ 1 MOREASSIGNED

Closed

9/25/2026, 3:06:30 PM

No activity in this phase yet.

03Sludge Pulse
hammz assigned hammz9/25/2026, 2:49:20 PM
Editable. Press Enter to edit.

shelson commented 9/25/2026, 10:16:53 AM

Also suspected as the cause of general terminal state corruption (cursor behavior, display glitches) in agent-harness sessions — the same leaked init/restore sequences that break JSON parsing also leave the terminal in a corrupted state.

hammz commented 9/25/2026, 2:55:54 PM

@shelson I was unable to repro this, I tried model search, data list, workflow search, model type search, extension list, vault list, workflow history search and model get with --json, both piped and under a full terminal (captured the raw bytes), and every run had zero escape sequences.

My agent tells me that: The pair \e[?12l\e[?25h ; is the terminfo "cursor normal" sequence. It shows up when vim, nano or other ncurses programs exit, from tput cnorm, or when tmux or screen passes an app's bare \e[?25h on to the outer terminal. A tmux-based agent harness would turn swamp's show-cursor into exactly the reported bytes. That also fits the escape appearing on its own line after the final }.

Could this be a side effect of your multiplexer setup or another aspect of your workflow? Let me know how you're running swamp here and I can dig further in

shelson commented 9/25/2026, 3:04:36 PM

Sorry PEBKAC :D

shelson commented 9/25/2026, 3:05:02 PM

(i.e this was my problem not swamp

hammz commented 9/25/2026, 3:06:30 PM

Closing as not reproducible / not a swamp bug.

We could not reproduce this, and the evidence points to the bytes coming from outside swamp:

  • \033[?12l\033[?25h is the terminfo cnorm sequence. It is byte-for-byte what tput cnorm prints for TERM=xterm-256color (12 bytes, no trailing newline), and what vim and other ncurses programs write on exit.
  • The swamp binary contains no ?12l anywhere, and no swamp release has ever depended on a terminfo-based library. swamp's own cursor handling (Ink) only emits a bare \033[?25h, only to a TTY, and never in --json mode.
  • Re-running the second report exactly (swamp workflow list --json | od -c from the home directory, same error) gives 0 bytes on stdout, both piped and under a PTY. The only child process swamp starts on that path is git rev-parse, and its output is captured. We also checked every other command path (list, search, get, error paths) with the same result.

Because od received the bytes through the pipe, whatever wrote them had swamp's stdout open. That usually means swamp resolves to a wrapper, shim or shell function in that environment that runs tput cnorm (or a TUI) after the real binary exits. If you can still reproduce it, please reopen with the output of type -a swamp, and say whether running the binary by its absolute path still leaks.

shelson commented 9/27/2026, 12:34:02 AM

Is there a better way to close issues as "oops this was my problem not swamp" - sorry that didn't come across - I had worked out I was doing something silly - but if your lifecycle isn't comment/ripple aware maybe there's not a way?

Sign in to post a ripple.