Skip to content

cli: opencode api silently truncates piped stdout at 256 KiB boundary (rc=0) #60395

Closed as duplicate

Description

@scemama

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

  1. 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).
  2. Redirect to a file:
opencode api get "/api/session/{id}/message?limit=200" > out.json
# → 1,472,857 bytes, stable across 5 consecutive runs
  1. 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
  1. 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 api output (automation, SDK-adjacent tooling, CI) can silently receive corrupt JSON for large responses. A size check against the Content-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

  1. opencodejr commented on Oct 29, 2026

    @opencodejr
    Contributor

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

    The cause looks the same: the api handler 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.

  2. opencodejr commented on Oct 30, 2026

    @opencodejr
    Contributor

    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 get output 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.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions