Hmbown/CodeWhale · error

String(e?.message ?? e)

Error message

String(e?.message ?? e)

What it means

This is the proxy's top-level error funnel: if translating or relaying the upstream SSE stream throws, the server responds 500 with { error: <first 2000 chars of the exception message> }. The bare expression String(e?.message ?? e) is the message-extraction code, so the observed text mirrors whatever upstream/translation error occurred.

Solutions

  1. Check the upstream server logs and the 500 body's error text for the root cause
  2. Verify upstream API credentials and model name
  3. Confirm the upstream still emits Responses-style SSE that the translator understands
  4. Retry the request; if persistent, inspect translateResponsesSseToChat against the current upstream format
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight upstream check
const pre = await fetch(`${UPSTREAM_BASE}/v1/chat/completions`, { method: "POST", headers, body: JSON.stringify({ model, messages: [], max_tokens: 1 }) });
if (!pre.ok) throw new Error(`upstream unhealthy: ${pre.status}`);

Try / catch

try {
  await streamFromUpstream();
} catch (e) {
  console.error("proxy 500 origin:", String(e?.message ?? e).slice(0, 2000));
  // inspect upstream status/format before retrying
}

Prevention

When it happens

Trigger: Upstream returns non-SSE or malformed data, translateResponsesSseToChat throws on unexpected chunk shapes, the upstream request itself fails mid-stream, or an exception is thrown while writing the response.

Common situations: Upstream auth failure, upstream API change breaking the SSE translation, network drop between proxy and OpenAI, or a timeout aborting the fetch mid-stream.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/af094912d6160771. Report an issue: GitHub.

Appendix: source

Thrown at scripts/opencode-chat2responses-proxy.mjs:199

        const { done, value } = await reader.read();
        if (done) break;
        buf += decoder.decode(value, { stream: true });
        let idx;
        while ((idx = buf.indexOf("\n\n")) !== -1) {
          const chunk = buf.slice(0, idx + 2);
          buf = buf.slice(idx + 2);
          const translated = translateResponsesSseToChat(chunk, model);
          if (translated) res.write(translated);
        }
      }
      if (buf.trim()) {
        const translated = translateResponsesSseToChat(buf, model);
        if (translated) res.write(translated);
      }
      res.write(`data: [DONE]\n\n`);
      res.end();
    } catch (e) {
      res.writeHead(500, { "content-type": "application/json" });
      res.end(JSON.stringify({ error: String(e?.message ?? e).slice(0, 2000) }));
    }
  });
});

server.listen(LISTEN_PORT, "127.0.0.1", () => {
  console.log(`[opencode-proxy] listening on http://127.0.0.1:${LISTEN_PORT}/v1/chat/completions -> ${UPSTREAM_BASE}${UPSTREAM_PATH}`);
  console.log(`[opencode-proxy] health: http://127.0.0.1:${LISTEN_PORT}/health`);
});

View on GitHub (pinned to 433685b202)