Relationships
#1866 `--server` list commands render the TUI picker into a non-TTY pipe
Opened by magistr · 8/27/2026· Shipped 8/27/2026
What happens
swamp model list --server <url> renders the interactive TUI picker even when
stdout is not a TTY. The same command run locally correctly detects the
non-interactive context and falls back to JSON, so the --server path appears
to skip the TTY check the local path applies.
Two consequences when the output is piped or captured (scripts, CI, agents):
- The pipe receives the full-screen picker — box-drawing characters, ANSI cursor-movement escapes, and repeated repaints — instead of parseable data.
- React emits a duplicate-key warning into that stream whose key is itself a stack-trace line:
Encountered two children with the same key, ` at recursivelyTraversePassiveMountEffects
(file:///.../react-reconciler/0.33.0/cjs/react-reconciler.development.js:12934:11)`.
Keys should be unique so that components maintain their identity across updates.(That frame name is recursivelyTraverse + PassiveMountEffects joined — it is
split above only because this tracker's secret scanner flags the joined form as a
credential and redacts it.)
A stack-trace frame being used as a React key suggests the remote path is
feeding diagnostic/log lines into the same collection the picker renders, where
two frames from one trace collide. That part is a hypothesis — the TTY-detection
difference is the directly observed behaviour.
Reproduction
# Local — correct: emits JSON when piped
swamp model list | head -3
# {
# "query": "",
# "results": [
# Remote — wrong: renders the TUI picker into the pipe
swamp model list --server wss://<serve-host> | head -3
# ─swamp──────────────────────────────────── models search ──
# > ▏ 4 / 4
# ─────────────────────────────────────────────────────────────
# The React warning, once per invocation:
swamp model list --server wss://<serve-host> 2>&1 | grep -c 'same key' # 1Expected
--server should honour the same non-TTY detection as the local path and emit
the default non-interactive output when stdout is not a TTY, without --json
having to be passed explicitly.
Scope
- Reproduces on
swamp model list --serverandswamp workflow list --server. - Reproduces against two independent
swamp serveinstances, so it is client-side, not a property of one server. - Consistent: 1 warning per invocation across repeated runs.
- Does NOT reproduce on the same commands run locally.
--jsonis a complete workaround — the remote call itself works correctly and returns the right data.
Environment
- swamp
20260827.012103.0-sha.89734f5f(client, macOS 14 / Darwin 23.6.0) - serve reached over
wss://through a Traefik TLS terminator - react-reconciler 0.33.0 (bundled in the compiled binary)
Impact
Low severity, since --json avoids it entirely. Worth fixing because the
failure is silent for anyone scripting against a remote serve: the command exits
0 and the pipe fills with escape sequences rather than data, so a naive parser
sees garbage rather than an error.
Shipped
Click a lifecycle step above to view its details.