Repository navigation
Description
Summary
opencode api get silently truncates large response bodies when stdout is a pipe: the output ends mid-JSON-string at 256 KiB / 320 KiB boundaries, with exit code 0 and no error on stderr. Redirecting to a file returns the full body. Consumers piping the CLI (scripts, subprocess capture) get corrupt JSON with no signal that anything went wrong.
Environment
- opencode version: 2.1.2
- OS: Linux 6.8.0-147-generic (linux x64)
- Terminal: TERM=xterm-256color, COLORTERM=truecolor
- Shell: /bin/bash
- Install/channel: latest (standalone binary,
~/.opencode/bin/opencode) - Active plugins: None found in config
Reproduction
- Find any GET endpoint whose response body exceeds 256 KiB. We used the session message list of a large session:
opencode api get "/api/session/{sessionID}/message?limit=200"(body: 1,472,857 bytes). - Redirect to a file:
opencode api get "/api/session/{id}/message?limit=200" > out.json
# → 1,472,857 bytes, stable across 5 consecutive runs- Pipe the output (any pipe consumer):
opencode api get "/api/session/{id}/message?limit=200" | cat > out2.json
# → 262,144 bytes (exactly 256 KiB), body ends mid-string- Pipe from a program (Python):
import subprocess
r = subprocess.run(
["opencode", "api", "get", "/api/session/{id}/message?limit=200"],
capture_output=True, text=True)
print(len(r.stdout), r.returncode, r.stderr)
# → 259721 rc=0 stderr='' (first run)
# → 422484 rc=0 stderr='' (second run)
# both truncate mid-JSON; json.loads() fails with "Unterminated string"Expected Behavior
The full response body on stdout, identical to the file-redirect case, regardless of whether stdout is a TTY, file, or pipe.
Actual Behavior
When stdout is a pipe, the written body stops at a multiple of 64 KiB (observed: 262,144 = 256 KiB, and 259,721 / 422,484 ≈ 253.6 / 412.6 KiB via subprocess), mid-string in the middle of the JSON document. Exit code is 0 and stderr is empty, so the truncation is completely silent. File redirection is always complete and stable.
Additional Context
- Truncation boundaries are exact 64 KiB multiples, consistent with the final buffered chunk(s) being dropped on process exit when stdout is a pipe (buffered write not flushed, or non-blocking write loss on EAGAIN at shutdown).
- Reproduced consistently on 2026-10-30 with 2.1.2 (multiple runs, two different capture methods); file redirect never truncated in ~10 runs.
- Impact: any scripted consumption of
opencode apioutput (automation, SDK-adjacent tooling, CI) can silently receive corrupt JSON for large responses. A size check against theContent-Length/body, or simply flushing before exit, should fix it; a warning when stdout is a pipe and the body exceeds some threshold would at least make it detectable.
Activity
opencodejr commentedon Oct 29, 2026
Thanks for the detailed report and measurements, @scemama! I think this is a duplicate of #52925, which reports the same problem:
opencode api getoutput is truncated when stdout is a pipe, the exit code is 0, and redirecting to a file gives the full body. Your 2.1.2 data confirms it is still there.Possible duplicates and related issues, ordered from most to least likely:
opencode api gettruncates stdout when it is a pipe (same symptom, same 262,144-byte cut-off, labelled reproduced)opencode apipipe truncation, reported on 2.2.1session export--completionsoutput cut off at 64 KiBThe cause looks the same: the
apihandler writes the body to stdout and the CLI exits before a pipe has taken all of it. There's an open PR for this, #52955. Until then, redirecting to a file first (as you found) is a workaround.The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different.
opencodejr commentedon Oct 30, 2026
Closing this as a duplicate of #52925, since there has been no reply saying how this differs. That issue covers the same problem:
opencode api getoutput is cut off when stdout is a pipe, the exit code is 0, and redirecting to a file gives the full body. Please follow #52925 and the open PR #52955 for progress. Until then, redirecting to a file first is a workaround.Thanks again for the detailed measurements, @scemama. If your case turns out to be different, reply here and we can reopen it.