paperclipai/paperclip · error

OpenCode event stream closed before the session became termi

Error message

OpenCode event stream closed before the session became terminal

What it means

Thrown when the SSE event stream from the OpenCode server ends (server closed the connection) while the session has not yet reached a terminal state. After up to 3 reconnect attempts the driver gives up and raises this so the caller knows the turn never completed.

Source

Thrown at packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts:1222

                ],
                reason: "OpenCode SSE frame parsed as JSON",
              });
            }
          } catch (error) {
            if (frameId) {
              this.#runtime.trace?.interpretation({
                frameId,
                stage: "typescript_opencode_sse_parse",
                ruleId: "opencode.sse.invalid_json",
                disposition: "rejected",
                reason: `OpenCode SSE data was not valid JSON: ${String(error).slice(0, 400)}`,
              });
            }
            throw error;
          }
          this.#mapProviderEvent(event, frameId);
        }
        throw new Error(
          "OpenCode event stream closed before the session became terminal",
        );
      } catch (error) {
        if (this.#closed || this.#abort.signal.aborted) return;
        attempts += 1;
        if (attempts > 3) {
          this.#emit("harness.diagnostic", {
            code: "opencode_sse_failed",
            message: redact(String(error), this.#runtime.sensitiveValues),
          });
          this.#events.fail(error);
          return;
        }
        await new Promise((resolve) => setTimeout(resolve, 50 * attempts));
      }
    }
  }

View on GitHub (pinned to 01ad858492)

Solutions

  1. Inspect the OpenCode server logs for a crash or restart at the time of the drop and fix the underlying server failure.
  2. Check that reconnect/backoff (attempts up to 3) is not being exhausted by frequent drops — increase stability of the host or the server.
  3. If aborts were not intended, verify this.#abort is not being signaled by an upstream timeout that closes the stream.
  4. Retry the turn; if the session is recoverable, re-attach with the provider session id instead of starting over.
Defensive patterns

Strategy: retry

Try / catch

try {
  await runTurn();
} catch (e) {
  if (e instanceof Error && e.message.includes("closed before the session became terminal")) {
    // inspect server logs for crash; reconnect using persisted providerSessionId and resume or re-run the turn
  }
}

Prevention

When it happens

Trigger: The OpenCode server process exits, restarts, or drops the SSE connection while the harness session is still awaiting a terminal event (e.g. turn completion), and reconnection attempts exceed the retry limit (attempts > 3).

Common situations: OpenCode server crashes mid-turn (OOM, panic); supervisor restarts the server during a long-running turn; network idle timeout closes the connection; machine sleep/resume breaks the socket.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/b0b2c642ff026669. Report an issue: GitHub.