paperclipai/paperclip · error
Environment driver " " does not support orphan sandbox…
Error message
Environment driver "${driver.driver}" does not support orphan sandbox teardown. What it means
retryPendingSandboxTeardown delegates to the environment driver resolved from the lease. Not all drivers implement retryPendingSandboxTeardown (it is optional); when the resolved driver lacks it, the runtime throws 'Environment driver "X" does not support orphan sandbox teardown.'
Solutions
- Route the retry to the driver that originally owned the sandbox (fix getLeaseDriverKey/lease metadata)
- Upgrade or select a driver that supports orphan sandbox teardown
- Skip teardown-retry for drivers that don't support it — check driver.retryPendingSandboxTeardown before calling
Example fix
// before
await runtime.retryPendingSandboxTeardown({ environment, lease });
// after
const key = getLeaseDriverKey(lease, environment);
if (driverSupportsTeardown(key)) await runtime.retryPendingSandboxTeardown({ environment, lease });
else logger.warn({ leaseId: lease.id }, 'driver does not support orphan teardown'); Defensive patterns
Strategy: validation
Validate before calling
const key = getLeaseDriverKey(lease, environment);
const driver = getDriver(key);
if (!driver?.retryPendingSandboxTeardown) {
console.warn(`Driver ${key} cannot retry orphan sandbox teardown; skipping`);
} Type guard
function supportsTeardown(d: EnvironmentDriver): d is EnvironmentDriver & Required<Pick<EnvironmentDriver, "retryPendingSandboxTeardown">> {
return typeof d.retryPendingSandboxTeardown === "function";
} Try / catch
try {
await runtime.retryPendingSandboxTeardown({ environment, lease });
} catch (e) {
if (e instanceof Error && e.message.includes("does not support orphan sandbox teardown")) {
// skip or manually clean the sandbox via the owning driver
} else throw e;
} Prevention
- Check driver capability flags before invoking optional driver operations
- Keep lease driver keys in sync when migrating environments between drivers
- Filter recovery/cleanup jobs to teardown-capable drivers
- Add capability introspection to driver registries instead of relying on throw-on-call
When it happens
Trigger: Invoking orphan sandbox teardown retry for a lease whose driver (e.g., a driver without sandbox lifecycle support) has no retryPendingSandboxTeardown implementation.
Common situations: Switching an environment between drivers (e.g., local vs cloud) and then retrying teardown recorded under the old driver; admin/recovery tooling that calls teardown retry unconditionally for all leases.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Sandbox driver does not support duplex channels for this…
- A sandbox command is required.
- ACPX runtime does not expose session goal controls
- ACPX session goal action
- [adapter-ui-loader] Failed to load UI parser for
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/2c5e382d23ce819a.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/environment-runtime.ts:3839
return released;
},
// Tear an orphan ephemeral sandbox down from its recorded provider config.
// A failed acquire records the orphan as a `pending_cleanup` lease. The row
// keeps the provider, the provider lease id, and the sandbox config, so this
// teardown runs without the environment row and accepts a null environment.
// The teardown resolves the recorded secret refs through the durable orphan
// record, so a deleted or foreign-bound environment never strands it. The
// caller owns the lease release; this dispatcher only runs the provider
// teardown and throws when the driver teardown throws.
async retryPendingSandboxTeardown(input: {
environment: Environment | null;
lease: EnvironmentLease;
}): Promise<unknown> {
const driver = requireDriverKey(getLeaseDriverKey(input.lease, input.environment));
if (!driver.retryPendingSandboxTeardown) {
throw new Error(
`Environment driver "${driver.driver}" does not support orphan sandbox teardown.`,
);
}
return await driver.retryPendingSandboxTeardown(input);
},
// Report whether the provider worker can run an orphan teardown now. The
// cleanup sweep calls this before it claims a finite retry attempt, so a
// briefly-down plugin worker never burns an attempt. This dispatcher never
// throws: an unregistered driver, or a driver with no probe, reports ready,
// so the teardown still runs and its own failure counts toward the cap.
async isPendingCleanupWorkerReady(input: {
environment: Environment | null;
lease: EnvironmentLease;
}): Promise<boolean> {
const driver = getDriver(getLeaseDriverKey(input.lease, input.environment));
if (!driver?.isPendingCleanupWorkerReady) return true;
return driver.isPendingCleanupWorkerReady(input);View on GitHub (pinned to 3f1d897a7c)