Skip to content

opencode run --format=json emits terminal step_finish but never exits #44901

Closed as not planned

Description

@RadomirMinkov

Description

In non-interactive mode, opencode run --format=json can finish the primary session, emit a terminal step_finish event with reason: "stop", and then remain alive indefinitely.
The model has finished, all tool calls are complete, and no additional output or provider requests occur. The process still does not return control to its parent and must be terminated externally.
This is a general CLI lifecycle issue affecting scripts, CI jobs, subprocess callers, and other automation that expects opencode run to exit after completion.

Actual behavior

The final JSON event is a successful terminal event:

{
"type": "step_finish",
"sessionID": "ses_...",
"part": {
"type": "step-finish",
"reason": "stop"
}
}

After emitting this event:

  • No further JSON events are written.
  • No additional model requests are made.
  • stdin is already closed.
  • No permission prompt is pending.
  • The opencode process remains alive.
  • The external timeout command eventually terminates it and returns exit code 124.

Expected behavior

After the primary session emits step_finish with reason: "stop":

  1. OpenCode should complete any pending output flush.
  2. The event subscription and local server resources should be closed.
  3. opencode run should exit promptly with code 0.

A structured terminal error should similarly close resources and exit with a nonzero status.

Suspected lifecycle problem

In packages/opencode/src/cli/cmd/run.ts, the JSON event loop emits step_finish when it observes a step-finish part, but the loop only breaks after a separate session.status event with status idle.

The command also awaits client.session.prompt(...) before awaiting completion of the event consumer.

This appears to leave at least two possible hang paths:

  • A terminal step-finish event is emitted, but session.status: idle is not observed.

  • The terminal event is emitted, but the outstanding client.session.prompt(...) request does not settle.

The non-interactive command should have one coordinated terminal lifecycle:
terminal completion should settle the prompt operation, stop the event subscription, release local server/runtime handles, and return the correct exit code.

Suggested regression test

Add a process-level test that:

  1. Spawns opencode run --format=json as a child process.

  2. Runs a tool-using session.

  3. Confirms that the primary session emits:

    {"type":"step_finish","part":{"reason":"stop"}}

  4. Requires the child process to exit with code 0 within a short grace period.

  5. Fails if the terminal event is emitted but the child remains alive.

Testing only the internal session state would not catch leaked handles or an unresolved CLI request; the test should observe the actual child process.

Related issues

This distinguishes the report from permission hangs, API retry loops, or models that never finish. The critical evidence is: **OpenCode itself emitted its successful terminal event, but the CLI process did not honor it.

Plugins

No response

OpenCode version

1.18.21

Steps to reproduce

Run OpenCode non-interactively with a prompt that requires several tool calls:

timeout 600s opencode \
  --model=<provider>/<model> \
  run \
  --format=json \
  --thinking \
  --dangerously-skip-permissions \
  -- "Inspect this repository, implement the requested fix, and run the relevant tests." \
  </dev/null >opencode.jsonl 2>opencode.stderr

echo "exit code: $?"
tail -n 5 opencode.jsonl

The issue is intermittent depending on the task, but occurred in four out of five independent tool-using runs.

### Screenshot and/or share link

_No response_

### Operating System

_No response_

### Terminal

_No response_

Activity

  1. github-actions commented on Aug 25, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  2. thdxr commented on Oct 11, 2026

    @thdxr
    Member

    Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.

    — from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions