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 2The 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
- Run any
swamp xxx xxxx --jsoncommand (occurs in agent-harness environments) - Pipe to
jqorcat -v - Observe cursor control escapes interleaved with JSON output
Related
- #430 —
--jsonoutput is polluted by non-JSON content (shipped) - #2414 —
swamp --versionemits ANSI escapes when piped (shipped) - #1866 —
--serverlist 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.
Closed
No activity in this phase yet.
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[?25his the terminfocnormsequence. It is byte-for-byte whattput cnormprints for TERM=xterm-256color (12 bytes, no trailing newline), and what vim and other ncurses programs write on exit.- The swamp binary contains no
?12lanywhere, 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 -cfrom 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 isgit 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.