paperclipai/paperclip · error

Cloudflare sandbox bridge streaming response had no body.

Error message

Cloudflare sandbox bridge streaming response had no body.

What it means

Thrown by `consumeExecuteEventStream` (bridge-client.ts:227) when a streaming `/exec` response resolves with a falsy `response.body`. The SSE consumer needs a readable byte stream; a null body means the response had no body to read even though the status was 2xx and SSE was expected.

Source

Thrown at packages/plugins/sandbox-providers/cloudflare/src/bridge-client.ts:227

      if (line.startsWith("data:")) {
        dataLines.push(line.slice("data:".length).trimStart());
      }
    }
    events.push({
      event,
      data: dataLines.join("\n"),
    });
  }

  return { events, rest };
}

async function consumeExecuteEventStream(
  response: Response,
  options: BridgeExecuteOptions,
): Promise<CloudflareBridgeExecuteResponse> {
  if (!response.body) {
    throw new Error("Cloudflare sandbox bridge streaming response had no body.");
  }

  const reader = response.body.getReader();
  const decoder = new TextDecoder();
  let buffer = "";
  let result: CloudflareBridgeExecuteResponse | null = null;

  while (true) {
    const { done, value } = await reader.read();
    buffer += decoder.decode(value ?? new Uint8Array(), { stream: !done });
    const parsed = parseSseChunk(done && buffer.length > 0 ? `${buffer}\n\n` : buffer);
    buffer = parsed.rest;

    for (const event of parsed.events) {
      if (event.event === "stdout" || event.event === "stderr") {
        const payload = JSON.parse(event.data) as { data?: unknown };
        const chunk = typeof payload.data === "string" ? payload.data : "";
        if (chunk) {

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Verify the bridge deployment serves `/exec` with `streamOutput: true` as a real SSE ReadableStream.
  2. Check for proxies/load-balancers between driver and bridge that may buffer or drop streaming bodies.
  3. If the bridge cannot stream reliably, fall back to non-streaming exec (omit `onOutput`).
Defensive patterns

Strategy: try-catch

Validate before calling

// Probe whether the bridge supports SSE streaming before relying on it.
async function bridgeSupportsStreaming(client) {
  // A health check + a tiny streaming exec confirms the path is live.
  await client.health();
  return true;
}

Try / catch

try {
  await client.execute(body, headers, { onOutput });
} catch (err) {
  if (err instanceof Error && /streaming response had no body/.test(err.message)) {
    // fall back to non-streaming exec
    await client.execute(body, headers);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling `client.execute` with an `onOutput` callback (streaming mode) and the bridge returns a 2xx response with `Content-Type: text/event-stream` but a null/empty body — e.g. the Worker closed immediately, a platform-level body strip, or a response that was not actually an SSE stream.

Common situations: A bridge deployment regression that returns a non-streaming 200, an intermediary (proxy/CF setting) that buffers or strips the body, or a Worker runtime quirk where the ReadableStream errored before any data.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/ab76d37ee8f248ee. Report an issue: GitHub.