paperclipai/paperclip · warning

Bridge host response body capacity is busy.

Error message

Bridge host response body capacity is busy.

What it means

Before the host encodes and writes a bridge response, it reserves 4 * sandboxBridgeEnvelopeLimit(responseBytes) bytes against the process memory ledger. If the ledger cannot grant that reservation (other in-flight requests have claimed the budget), the host fails this request rather than over-committing memory. This is a transient back-pressure signal, not a size violation of the response itself.

Solutions

  1. Retry the request after a short backoff; capacity frees when in-flight responses complete.
  2. Reduce concurrent sandbox bridge requests or queue them client-side.
  3. Increase the bridge's total response capacity / memory ledger configuration.
Defensive patterns

Strategy: retry

Try / catch

try { return await bridge.dispatch(req); } catch (e) {
  if (e.message.includes("capacity is busy")) { await sleep(backoff); return bridge.dispatch(req); }
  throw e;
}

Prevention

When it happens

Trigger: reservation.reserve(4 * sandboxBridgeEnvelopeLimit(responseBytes)) returns false because concurrent bridge traffic has already consumed the shared byte budget.

Common situations: Many sandbox callbacks firing at once (fan-out tools); a slow handler pinning its reservation while other requests queue; budget sized for single-request workloads but hit under parallel agent runs.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/070d31fa559392e8. Report an issue: GitHub.

Appendix: source

Thrown at packages/adapter-utils/src/sandbox-callback-bridge.ts:1131

      // the handler writes the real response.
      if (!claimForHandler()) {
        return;
      }

      // Build the response, then finalize once. The handler already holds the
      // claim, so `finalize` writes the real response.
      let response: SandboxCallbackBridgeResponse;
      let handlerReturned = false;
      try {
        const { bodyEncoding, ...forwardRequest } = request;
        const result = await input.handleRequest({ ...forwardRequest,
          body: bodyEncoding === "base64" ? decodeSandboxBridgeBody(request, maxBodyBytes) : request.body,
        }, { signal: guard.controller.signal, reservation });
        handlerReturned = true;
        const responseBytes = Buffer.byteLength(result.body ?? "");
        if (responseBytes > maxBodyBytes) throw new Error("Bridge response body exceeded the configured size limit.");
        if (!reservation.reserve(4 * sandboxBridgeEnvelopeLimit(responseBytes))) {
          throw new Error("Bridge host response body capacity is busy.");
        }
        const responseBody = encodeSandboxBridgeBody(result.body ?? "", maxBodyBytes);
        response = {
          id: request.id,
          status: result.status,
          headers: result.headers ?? {},
          ...responseBody,
          completedAt: new Date().toISOString(),
        };
      } catch (error) {
        console.warn(
          `[paperclip] sandbox callback bridge handler failed for ${request.id}: ${error instanceof Error ? error.message : String(error)}`,
        );
        // Tell a worker abort apart from a normal handler failure. The recovery
        // path aborts `guard.controller` when the per-iteration timeout or the
        // watchdog fires. The abort reaches this catch only after the handler
        // claimed the request and started the host operation. The bridge cannot
        // cancel a host operation that is in flight, so the mutation may have

View on GitHub (pinned to 3f1d897a7c)