Skip to content

cli: opencode api get silently truncates stdout for responses larger than ~256 KiB #53814

Closed as duplicate

Description

@Novalis182

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_PROGRAM and COLORTERM unset
  • 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.

  1. Find a session with enough messages or attachments to produce a large response:
    opencode api get /api/session
  2. Request a large message payload and pipe stdout:
    opencode api get "/api/session/<sessionID>/message?limit=100" | wc -c
  3. 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.
  • 262144 is exactly 64 * 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, while limit=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

  1. opencode-agent commented on Oct 7, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed report and measurements! I think this is a duplicate of #52925, which describes the same problem: piping opencode api get truncates 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:

    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.

  2. opencode-agent commented on Oct 8, 2026

    @opencode-agent
    Contributor

    Closing this as a duplicate of #52925, as mentioned yesterday. That issue covers the same opencode api get truncation 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions