Hmbown/CodeWhale · error

${compactRuntimeError(response.status, body)}

Error message

${compactRuntimeError(response.status, body)}

What it means

The Weixin bridge's streamTurnEvents throws compactRuntimeError(response.status, body) when the SSE endpoint responds with a non-OK status, before consuming any events. The error carries the HTTP status and any error details from the JSON body, turning runtime-side rejections into an explicit failure instead of an empty or broken event stream.

Solutions

  1. Address the status shown in the message: fix auth for 401/403, fix runtimeUrl for 404, back off for 429, check runtime logs for 5xx.
  2. Confirm the runtime service is running and reachable at the configured address.
  3. Update the token/secret used by authHeaders().

Example fix

// before
WEIXIN_BRIDGE_RUNTIME_URL=http://localhost:7000  # runtime on 8080
// Error: 404 ...

// after
WEIXIN_BRIDGE_RUNTIME_URL=http://localhost:8080
Defensive patterns

Strategy: retry

Validate before calling

const base = process.env.WEIXIN_BRIDGE_RUNTIME_URL;
const res = await fetch(`${base}/health`);
if (!res.ok) throw new Error(`Runtime not ready: HTTP ${res.status}`);

Try / catch

async function streamWithRetry(input, attempts = 3) {
  for (let i = 0; i < attempts; i++) {
    try {
      for await (const event of streamTurnEvents(input)) handle(event);
      return;
    } catch (err) {
      if (/^(429|5\d\d)/.test(err.message) && i < attempts - 1) {
        await delay(1000 * 2 ** i);
        continue;
      }
      throw err;
    }
  }
}

Prevention

When it happens

Trigger: fetch of the turn-events SSE endpoint resolves with response.ok false: 401/403 (bad auth headers), 404 (wrong runtimeUrl or path), 429 (rate limiting), or 5xx (runtime fault).

Common situations: Wrong port/host in runtime configuration, expired credentials, runtime restart invalidating tokens, or a proxy/load balancer returning 502/503 while the runtime is down.

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 Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/729a40b4df71b433. Report an issue: GitHub.

Appendix: source

Thrown at integrations/weixin-bridge/src/index.mjs:420

  const timeout = setTimeout(
    () => controller.abort(),
    config.turnTimeoutMs
  );
  let responseText = "";
  let latestSeq = sinceSeq;
  let sentProgressAt = Date.now();

  try {
    const response = await fetch(
      `${config.runtimeUrl}/v1/threads/${encodeURIComponent(threadId)}/events?since_seq=${sinceSeq}`,
      {
        headers: authHeaders(),
        signal: controller.signal,
      }
    );
    if (!response.ok) {
      const body = await readJsonSafe(response);
      throw new Error(compactRuntimeError(response.status, body));
    }

    for await (const event of readSse(response)) {
      if (!event.data) continue;
      const record = JSON.parse(event.data);
      latestSeq = Math.max(latestSeq, Number(record.seq || 0));
      await threadStore.patchChat(chatId, { lastSeq: latestSeq });

      if (turnId && record.turn_id && record.turn_id !== turnId) continue;

      if (
        record.event === "item.delta" &&
        record.payload?.kind === "agent_message"
      ) {
        responseText += record.payload.delta || "";
        const now = Date.now();
        if (
          responseText.length > config.maxReplyChars &&

View on GitHub (pinned to 433685b202)