Repository navigation
Description
Summary
opencode api get silently truncates stdout when the response exceeds roughly 256 KiB and stdout is a pipe. The command exits with code 0 and writes nothing to stderr, so a partial JSON document is returned without any error. The same request redirected to a file returns the complete response.
Environment
- opencode version: v2.0.16 (CLI on
PATH, installed at~/.opencode/bin/opencode) and v2.0.22 (CLI bundled with the desktop app, which is what was running as the local background service). Both versions reproduce the bug. - OS: Linux 7.2.5-3-omarchy, x86_64 (Omarchy / Arch-based)
- Terminal:
TERM=xterm-256color,TERM_PROGRAMandCOLORTERMunset - Shell: /usr/bin/bash
- Install/channel: CLI installed via the standalone binary; desktop app 2.0.22 also installed
- Active plugins: none (config defines only remote/local MCP servers)
Reproduction
Requires a session whose message list response exceeds ~256 KiB. Sessions containing image attachments reach this quickly, because message payloads inline base64 attachments.
- Find a session with enough messages or attachments to produce a large response:
opencode api get /api/session
- Request a large message payload and pipe stdout:
opencode api get "/api/session/<sessionID>/message?limit=100" | wc -c
- Request the same payload and redirect stdout to a file:
opencode api get "/api/session/<sessionID>/message?limit=100" > out.json wc -c < out.json
Expected Behavior
Both forms should return the identical, complete response body, and stdout should not be truncated for any response size. At minimum, exceeding a buffer boundary should surface as a non-zero exit code or an error on stderr.
Actual Behavior
Step 2 returns a partial body; step 3 returns the full body.
Measured on one session, comparing the pipe form against the redirect form for identical requests:
| request | pipe (| wc -c) |
redirect (> file) |
|---|---|---|
limit=100 |
262144 bytes | 20065655 bytes |
The truncated output always ends mid-token — for the limit=100 request it stops partway through a base64 string — and is therefore not parseable:
json.decoder.JSONDecodeError: Unterminated string starting at: line 1 column 20262 (char 20261)
Observed characteristics:
- Exit code is
0, stderr is empty. The data loss is completely silent. - The number of bytes delivered varies between runs (261823 and 262144 were both observed for the same request), so it looks like a race between process exit and draining an async pipe write rather than a fixed truncation point.
262144is exactly64 * 4096, which suggests a page-buffer-sized flush boundary, but the varying sizes indicate the tail is simply lost rather than deliberately clipped.- There is a size threshold below which output is always complete. For one request,
limit=7(20251 bytes) was correct in 6/6 runs, whilelimit=8(471392 bytes) was truncated in 6/6 runs. - Redirecting to a file is unaffected, which points at the pipe path specifically.
Additional Context
Impact: this breaks any tooling that consumes large opencode api get responses through a pipe or subprocess capture — including paging through long sessions for analysis or export. The silent failure mode is the worst part: the caller receives a short, syntactically-invalid document with a success exit code, so it is easy to misdiagnose as bad session data rather than output truncation.
Workaround used: connect to the local service over HTTP directly, using the URL and password from ~/.local/state/opencode/service.json (HTTP Basic auth, username opencode). Responses over that path are complete and correct, and paging 684 messages completes in well under a second. opencode api get remains useful for small responses.
Activity
opencode-agent commentedon Oct 7, 2026
Thanks for the detailed report and measurements! I think this is a duplicate of #52925, which describes the same problem: piping
opencode api gettruncates large responses at 4096-byte multiples (including 262144), exits 0 and leaves invalid JSON, while redirecting to a file works.Possible duplicates and related issues, ordered from most to least likely:
opencode api geton v2.0.22, same pipe-versus-redirect behaviour and truncation sizes. The cause there is that the CLI exits before stdout has finished writing.opencode export <id> | jqproduces truncated / invalid JSON when piped (large sessions) #29330: the same symptom withopencode exportpiped tojq.Until that fix lands, redirecting to a file first or using the local HTTP service directly (as you did) avoids the truncation.
The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different.
opencode-agent commentedon Oct 8, 2026
Closing this as a duplicate of #52925, as mentioned yesterday. That issue covers the same
opencode api gettruncation when stdout is a pipe. Open PR #52955 targets it by waiting for stdout to finish writing before the CLI exits. Until then, redirecting to a file or calling the local HTTP service directly avoids the problem. Thanks again for the detailed measurements. If your case turns out to be different, reply here and we can reopen it.