paperclipai/paperclip · error

Sandbox driver does not support direct command execution…

Error message

Sandbox driver does not support direct command execution for built-in providers.

What it means

Capability guard on the sandbox driver's direct-execute path: a direct, session-less command execution was requested against a built-in sandbox provider, but built-in providers route commands through their own session/lease machinery and do not implement the direct execute method. The request is rejected instead of silently doing something else.

Solutions

  1. Use an environment driver that supports direct command execution, or route commands through the supported interface.
Defensive patterns

Strategy: validation

When it happens

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

Common situations: See trigger scenarios.


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

Appendix: source

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

          `Pending-cleanup lease "${input.lease.id}" has no recorded config for provider "${recordedProvider}".`,
        );
      }

      // Plugin-backed provider path. The Claude login runs on a plugin-backed
      // sandbox, so this path tears down the login orphan.
      if (!isBuiltinSandboxProvider(recordedProvider)) {
        if (!pluginWorkerManager) {
          throw new Error(
            `Sandbox provider "${recordedProvider}" needs a plugin worker manager for cleanup, but none is available.`,
          );
        }
        const pluginProvider = await resolveSandboxProviderPlugin({ provider: recordedProvider });
        if (pluginProvider.state !== "running") {
          throw new Error(
            `Sandbox provider plugin for "${recordedProvider}" is ${pluginProvider.state}, so the cleanup teardown cannot run yet.`,
          );
        }
        // Resolve the recorded secret refs through the durable orphan record,
        // not the environment binding. A delete removed the binding, or a
        // provider change replaced it, so environment-bound resolution would
        // reject the recorded API-key ref and strand the teardown forever.
        const config = await resolveSandboxCleanupConfigSecrets(
          db,
          input.lease.companyId,
          metadataConfig,
          { issueId: input.lease.issueId, heartbeatRunId: input.lease.heartbeatRunId },
        );
        const workerConfig = stripSandboxProviderEnvelope(config as SandboxEnvironmentConfig);
        return await pluginWorkerManager.call(
          pluginProvider.resolved.plugin.id,
          "environmentDestroyLease",
          {
            driverKey: recordedProvider,
            companyId: input.lease.companyId,
            // The provider teardown keys on the provider lease id. The
            // environment id is only context, and it is empty when a delete

View on GitHub (pinned to 3f1d897a7c)