paperclipai/paperclip · warning

[paperclip] sandbox callback bridge failed to abort queued r

Error message

[paperclip] sandbox callback bridge failed to abort queued requests after worker failure: ${failPendingError instanceof Error ? failPendingError.message : String(failPendingError)}

What it means

The bridge worker loop caught a fatal error (e.g. per-iteration timeout while listing or processing request files), surfaced it as a run-trace span via surfaceRunError, then called failPendingRequests(message, { abandonInFlight: true }) to abort queued requests with 503s. That abort itself threw — so this warning reports the cleanup failure. Queued request files may remain, and their sandbox callers stay pending until their own deadlines; the run has already recorded the primary worker failure.

Source

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

              `Sandbox callback bridge process request ${fileName}`,
            );
            lastSuccessfulIterationAt = Date.now();
          } finally {
            inFlight -= 1;
          }
        }
        lastSuccessfulIterationAt = Date.now();
        if (stopping && Date.now() >= stopDeadline) {
          break;
        }
      }
    } catch (error) {
      const message = buildWorkerFailureMessage(error);
      await surfaceRunError(new Error(message));
      try {
        await failPendingRequests(message, { abandonInFlight: true });
      } catch (failPendingError) {
        console.warn(
          `[paperclip] sandbox callback bridge failed to abort queued requests after worker failure: ${failPendingError instanceof Error ? failPendingError.message : String(failPendingError)}`,
        );
      }
    } finally {
      clearInterval(watchdogTimer);
      settled = true;
      if (settleResolve) {
        settleResolve();
      }
    }
  })());

  void loop;

  return {
    stop: async (options = {}) => {
      stopping = true;
      const drainMs = normalizeTimeoutMs(options.drainTimeoutMs, DEFAULT_BRIDGE_STOP_TIMEOUT_MS);

View on GitHub (pinned to a7e689b3c3)

Solutions

  1. Find the primary failure first: the run trace now contains the surfaced worker-failure span (surfaceRunError) — read it to see the root timeout/error.
  2. Verify and restore sandbox/storage health, then stop and re-run the affected agent turn so a fresh bridge drains or 503s leftover requests.
  3. Do not retry the run against the same sandbox until the channel responds (a quick list/write probe against the shared dir is a good smoke test).
  4. Report with run logs if recovery keeps failing on a healthy channel — that combination indicates a defect.
Defensive patterns

Strategy: try-catch

Validate before calling

const probe = await withTimeout(input.client.listJsonFiles(directories.requestsDir), iterationTimeoutMs, "probe");
// channel answers => safe to attempt failPendingRequests; otherwise expect stranded queue

Try / catch

try {
  await failPendingRequests(message, { abandonInFlight: true });
} catch (failPendingError) {
  // Best-effort cleanup failed on the same dead channel. The primary failure was
  // already surfaced to the run trace — log and let callers hit their own deadlines.
  console.warn(`[paperclip] sandbox callback bridge failed to abort queued requests: ${String(failPendingError)}`);
}

Prevention

When it happens

Trigger: Sandbox channel dies while requests are queued: the loop's listJsonFiles or a request write times out (worker failure), and the subsequent recovery sweep that writes 503 responses fails again on the same dead channel.

Common situations: Sandbox killed mid-run; shared storage unmounted; severe host I/O contention making every channel operation time out in sequence.

Related errors


AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-18). Data as JSON: /api/errors/0652120ef5ad5e8d. Report an issue: GitHub.