paperclipai/paperclip · error · Error
Daytona template deletion requires @daytonaio/sdk snapshot.g
Error message
Daytona template deletion requires @daytonaio/sdk snapshot.get/delete support.
What it means
Thrown by onEnvironmentDeleteTemplate after the templateKind guard passes. The plugin casts the Daytona client to expose an optional snapshot service and requires both client.snapshot.get and client.snapshot.delete to be functions before deleting. It fires when the installed @daytonaio/sdk does not ship the snapshot service (or shipped it under a different shape), so deletion cannot be performed safely.
Source
Thrown at packages/plugins/sandbox-providers/daytona/src/plugin.ts:2350
};
} finally {
sandboxHandleTeardownGates.end(scope, teardownGate);
evictSandboxHandle(scope);
}
},
async onEnvironmentDeleteTemplate(
params: PluginEnvironmentDeleteTemplateParams,
): Promise<PluginEnvironmentDeleteTemplateResult> {
const templateKind = params.templateKind ?? "snapshot";
if (templateKind !== "snapshot") {
throw new Error(`Daytona can delete snapshot templates only, not ${templateKind}.`);
}
const config = parseDriverConfig(params.config);
const client = createDaytonaClient(config) as Daytona & { snapshot?: DaytonaSnapshotService };
const snapshotService = client.snapshot;
if (typeof snapshotService?.get !== "function" || typeof snapshotService.delete !== "function") {
throw new Error("Daytona template deletion requires @daytonaio/sdk snapshot.get/delete support.");
}
const snapshot = await snapshotService.get(params.templateRef);
await snapshotService.delete(snapshot);
return {
deleted: true,
metadata: {
provider: "daytona",
templateKind: "snapshot",
templateRefRedacted: true,
reason: params.reason ?? null,
},
};
},
async onEnvironmentExecute(
params: PluginEnvironmentExecuteParams,
): Promise<PluginEnvironmentExecuteResult> {
if (!params.lease.providerLeaseId) {View on GitHub (pinned to 67001ec6eb)
Solutions
- Upgrade @daytonaio/sdk to a version that exposes client.snapshot.get and client.snapshot.delete (the repo pins 0.203.0); rebuild the provider.
- In tests, stub client.snapshot with both get and delete as vi.fn() before invoking delete-template.
- If the SDK removed/renamed the service, update the DaytonaSnapshotService type at plugin.ts:147 and the cast at plugin.ts:2347 to match the new surface.
Example fix
// before (test mock)
const client = { snapshot: {} };
// after
const client = {
snapshot: { get: vi.fn(), delete: vi.fn() },
}; Defensive patterns
Strategy: type-guard
Validate before calling
function snapshotDeletionSupported(client: unknown): boolean {
const s = (client as { snapshot?: { get?: unknown; delete?: unknown } }).snapshot;
return typeof s?.get === 'function' && typeof s?.delete === 'function';
}
// if (!snapshotDeletionSupported(client)) skip delete-template for this SDK. Type guard
type SnapshotService = {
get: (name: string) => Promise<unknown>;
delete: (snapshot: unknown) => Promise<void>;
};
function hasSnapshotService(
c: unknown,
): c is { snapshot: SnapshotService } {
const s = (c as { snapshot?: Partial<SnapshotService> }).snapshot;
return !!s && typeof s.get === 'function' && typeof s.delete === 'function';
} Try / catch
try {
await plugin.onEnvironmentDeleteTemplate(params);
} catch (err) {
if (err instanceof Error && /snapshot\.get\/delete support/.test(err.message)) {
// SDK cannot delete; leave the snapshot or fall back to manual cleanup
return { deleted: false };
}
throw err;
} Prevention
- Run a startup capability probe against @daytonaio/sdk and advertise delete-template only when client.snapshot is present.
- Pin the SDK version; re-run the provider's contract tests on any SDK bump.
When it happens
Trigger: Calling delete-template on a Daytona SDK version whose client has no snapshot service, or where snapshot.get / snapshot.delete are not functions; this is the delete-side analogue of the capture-side _experimental_createSnapshot capability check.
Common situations: SDK downgrade below the version that introduced the snapshot service; a custom/forked SDK build that omits the snapshot service; running delete-template in a test harness with a mock client that only stubs create.
Related errors
- Daytona template capture requires @daytonaio/sdk Sandbox._ex
- Daytona interactive setup requires @daytonaio/sdk Sandbox.cr
- Daytona SSH access did not return a token or SSH command.
- Cannot capture a Daytona template without a setup sandbox le
- Daytona can delete snapshot templates only, not ${templateKi
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/bca4599edffe3591.
Report an issue: GitHub.