paperclipai/paperclip · error

OpenCode API ${path} returned HTTP ${response.status}: ${red

Error message

OpenCode API ${path} returned HTTP ${response.status}: ${redact(responseRaw, runtime.sensitiveValues)}

What it means

Thrown when an OpenCode API request succeeds at the transport level but returns a non-2xx HTTP status. The message includes the request path, status code, and the (redacted) response body so the developer can see the server-side error reason. A trace interpretation with disposition 'rejected' is also recorded.

Source

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

  }
  const responseRaw = await response.text();
  const responseFrameId = runtime.trace?.frame({
    direction: "provider_to_client",
    raw: responseRaw,
    transport: "http_json",
    nativeMethod: `${method} ${path} ${response.status}`,
  });
  if (!response.ok) {
    if (responseFrameId) {
      runtime.trace?.interpretation({
        frameId: responseFrameId,
        stage: "typescript_opencode_http_parse",
        ruleId: `opencode.http.error.${response.status}`,
        disposition: "rejected",
        reason: `OpenCode API returned HTTP ${response.status}`,
      });
    }
    throw new Error(
      `OpenCode API ${path} returned HTTP ${response.status}: ${redact(responseRaw, runtime.sensitiveValues)}`,
    );
  }
  if (response.status === 204 || !responseRaw) {
    if (responseFrameId) {
      runtime.trace?.interpretation({
        frameId: responseFrameId,
        stage: "typescript_opencode_http_parse",
        ruleId: "opencode.http.empty_success",
        disposition: "operator_only",
        reason: "OpenCode API returned a successful empty response",
      });
    }
    return null;
  }
  try {
    const parsed = JSON.parse(responseRaw) as unknown;
    if (responseFrameId) {

View on GitHub (pinned to 01ad858492)

Solutions

  1. Read the status and redacted body in the message: 404 means the session id no longer exists on the server — recreate the session.
  2. 401/403: refresh the authHeader used to build the runtime.
  3. 400: compare the request payload against the installed OpenCode version's API schema (contract may have drifted).
  4. 5xx: check OpenCode server logs and retry; persistent 5xx is a server bug or resource exhaustion.

Example fix

// before
const res = await fetch(url, init); // 404 ignored until throw

// after
const res = await fetch(url, init);
if (res.status === 404) {
  // session vanished after server restart — recreate instead of reusing id
  providerSessionId = await createSession();
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!providerSessionId) throw new Error("Cannot call API before a session id exists");

Try / catch

try {
  await callOpenCodeApi(`/session/${id}`, { method: "POST", body });
} catch (e) {
  if (e instanceof Error) {
    const m = e.message.match(/returned HTTP (\d+)/);
    if (m && m[1] === "404") recreateSession(); // stale session id after server restart
    else if (m && m[1] === "401") refreshAuth();
  }
  throw e;
}

Prevention

When it happens

Trigger: Any OpenCode API endpoint replies with 4xx/5xx: 400 bad session payload, 401 bad authHeader, 404 unknown session/thread id, 409 conflicting state, 500 internal server error.

Common situations: Sending a threadId/sessionId from a previous server run to a restarted server (404); expired or wrong auth token (401); malformed request body after an API contract change (400); OpenCode internal error (500).

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


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