paperclipai/paperclip · error · SandboxOrphanCleanupWriteError

Sandbox provider "${input.provider}" leaked lease "${input.p

Error message

Sandbox provider "${input.provider}" leaked lease "${input.providerLeaseId ?? "unknown"}": the acquire could not tear it down and could not record a durable pending-cleanup row. The live sandbox has no durable cleanup state and needs a manual teardown.

What it means

Error "Sandbox provider "${input.provider}" leaked lease "${input.providerLeaseId ?? "unknown"}": the acquire could not tear it down and could not record a durable pending-cleanup row. The live sandbox has no durable cleanup state and needs a manual teardown." thrown in paperclipai/paperclip.

Source

Thrown at server/src/services/environment-runtime.ts:1381

          issueId: record.issueId,
          heartbeatRunId: record.heartbeatRunId,
          provider: record.provider,
          providerLeaseId: record.providerLeaseId,
          metadata: record.metadata,
          failureReason: DEFERRED_ORPHAN_CLEANUP_FAILURE_REASON,
        });
        // The durable row exists now, so the sweep finds and releases the orphan.
        // Drop the spooled copy only after the row lands. A crash between the two
        // leaves the spooled copy for a later flush, which re-inserts a duplicate
        // the idempotent teardown handles. This order never loses the orphan.
        await orphanCleanupSpool.remove(record);
        recovered += 1;
      } catch {
        // The database is still down. Re-queue the record for a later flush,
        // unless the buffer filled again. The identifiers carry no secret; the
        // caught write exception never enters the log, because it can hold a
        // credential in its message, code, cause, or stack.
        const requeued = enqueueDeferredOrphanCleanup(record);
        logger.warn(
          {
            errorKind: SANDBOX_ORPHAN_CLEANUP_WRITE_ERROR_KIND,
            provider: record.provider,
            providerLeaseId: record.providerLeaseId,
            companyId: record.companyId,
            environmentId: record.environmentId,
            requeued,
          },
          requeued
            ? "deferred sandbox orphan cleanup flush failed; kept the orphan buffered for a later flush"
            : "deferred sandbox orphan cleanup flush failed and the in-process buffer is full; live sandbox needs a manual teardown",
        );
      }
    }
    return { recovered, pending: deferredOrphanCleanups.length };
  };

View on GitHub (pinned to 01ad858492)

Solutions

  1. Manually tear down the leaked sandbox using the provider lease id in the message, then repair the cleanup row state.
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at server/src/services/environment-runtime.ts:1259 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-08-18). Data as JSON: /api/errors/5fa22737247877fe. Report an issue: GitHub.