Skip to content

Bug: opencode run output truncated in non-interactive mode - missing assistant response and step_finish #31365

@mingfang

Description

@mingfang

Bug Report

When using opencode run in non-interactive mode, the output is truncated after step_start. The assistant response text and step_finish event are never emitted.

This affects all output formats (JSON, plain text, etc.) — not just --format json. The core issue is that the event subscription is fire-and-forget and the process exits before events finish flowing through.

Steps to Reproduce

bun opencode run "What is 2+2?" --format json

Expected Output

All events should be emitted:

  1. text - user message
  2. step_start - step initiated
  3. text - assistant response
  4. step_finish - step completed

Actual Output

Only text (user message) and step_start are emitted. The process exits before emitting:

  • The assistant response text event
  • The step_finish event

Root Cause

In commit eab329d0de (fix(run): restore non-interactive exit behavior #27371), the loop function was changed from await completed to fire-and-forget.

Before (correct):

const completed = loop(client, events)
await client.session.prompt({...})
const error = await completed  // waits for event loop to finish

After (broken):

loop(client, events).catch(...)  // fire-and-forget
await client.session.prompt({...})
return  // process exits before cleanup events emit

The event subscription runs asynchronously. When prompt returns and the function exits, the SSE subscription hasn't finished emitting the remaining events (assistant text stream, step-finish). The process terminates, truncating the output.

Why It Doesn't Affect Interactive Mode

Interactive mode (opencode run "message" without --format json) keeps the TUI/CLI alive until the user exits. Events continue to flow as long as the process is running. Non-interactive mode exits immediately after prompt returns.

Impact

  • Programmatic output broken: Any consumer of opencode run stdout gets an incomplete response
  • Sessions appear hung: Users see the assistant appear to not respond
  • Tool calls silently dropped: Tool execution events after step_start are never emitted

Proposed Fix

Either:

  1. Revert the loop to be awaited (like before commit eab329d), or
  2. Add a mechanism to wait for session idle before exiting (e.g., polling session.status() until idle, then a short delay for SSE cleanup)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions