paperclipai/paperclip · error
OpenCode event stream returned HTTP ${response.status}
Error message
OpenCode event stream returned HTTP ${response.status} What it means
Thrown when the driver opens the OpenCode server's SSE event stream and the HTTP response is not ok or has no body. The message embeds the HTTP status so the developer can see whether the endpoint rejected auth, was not found, or the server is unhealthy.
Source
Thrown at packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts:1160
},
},
{ turnId, itemId: request.itemId },
);
}
async #pumpEvents(): Promise<void> {
let attempts = 0;
while (!this.#closed && !this.#abort.signal.aborted) {
try {
const response = await this.#fetch(`${this.#runtime.baseUrl}/event`, {
headers: {
Authorization: this.#runtime.authHeader,
Accept: "text/event-stream",
},
signal: this.#abort.signal,
});
if (!response.ok || !response.body)
throw new Error(
`OpenCode event stream returned HTTP ${response.status}`,
);
const outboundFrameId = this.#runtime.trace?.frame({
direction: "client_to_provider",
raw: "",
transport: "http_sse",
nativeMethod: "GET /event",
});
if (outboundFrameId) {
this.#runtime.trace?.interpretation({
frameId: outboundFrameId,
stage: "typescript_opencode_http_transport",
ruleId: "opencode.http.GET_event",
disposition: "operator_only",
reason: "Opened the OpenCode server-sent event stream",
});
}
for await (const frame of parseSseFrames(response.body)) {View on GitHub (pinned to 01ad858492)
Solutions
- Check the HTTP status in the message: 401/403 means fix the authHeader; 404 means the event endpoint path changed (check server version).
- Verify the OpenCode server process is alive and healthy at the configured base URL before opening the stream.
- Confirm any proxy in front of OpenCode supports streaming responses and is not stripping the SSE body.
- Retry session startup — the driver already retries up to 3 times, so persistent failure means a configuration issue.
Example fix
// before
const res = await fetch(`${baseUrl}/event`, { headers });
// after
const res = await fetch(`${baseUrl}/event`, { headers });
if (res.status === 401) {
throw new Error("Event stream auth rejected — refresh authHeader from server health/startup");
} Defensive patterns
Strategy: retry
Validate before calling
const health = await fetch(`${baseUrl}/health`);
if (!health.ok) throw new Error(`OpenCode server unhealthy: HTTP ${health.status}`); Try / catch
try {
await openStream();
} catch (e) {
if (e instanceof Error && /event stream returned HTTP (401|403)/.test(e.message)) {
authHeader = await refreshAuth(); // re-auth before retrying
} else if (/event stream returned HTTP (502|503|504)/.test(e.message)) {
await backoff(); // transient upstream — retry with backoff
}
} Prevention
- Health-check the server before opening the event stream
- Keep the authHeader in sync with server restarts
- Verify proxies between client and server support SSE streaming
When it happens
Trigger: The driver issues a GET for the event stream with Authorization/Accept: text/event-stream headers and receives a non-2xx status (e.g. 401, 404, 502), or a 200 without a readable body.
Common situations: Wrong or expired authHeader after the server restarted with new credentials; proxy/load balancer returning 502/503; OpenCode server version whose event endpoint path differs; server crashed mid-startup.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Anthropic Managed Agents request failed with HTTP ${response
- The bridge host reached its reserved process body byte ceili
- OpenCode event stream closed before the session became termi
- OpenCode API ${path} request failed: ${redact(String(error),
- OpenCode SSE event exceeded the retained payload limit
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/25c6c4dcaa210ec7.
Report an issue: GitHub.