mastra-ai/mastra · error

Sandbox provider " " does not support stop.

Error message

Sandbox provider "${config.sandbox.provider}" does not support stop.

What it means

The worker deployment exposes a stop() operation, but the underlying sandbox provider adapter does not implement the optional stop capability. The library throws immediately rather than attempting an unsupported provider call.

Solutions

  1. Check the provider capabilities before calling stop: `if (sandbox.stop) await sandbox.stop(); else await sandbox.destroy();`
  2. Implement the optional `stop` method on your custom sandbox provider adapter if graceful stop is required.
  3. Use destroy() instead of stop() if hard teardown is acceptable.
  4. Switch to a sandbox provider that supports graceful stop if stop semantics are required.

Example fix

// before
await worker.stop();
// after
if (workerStopSupported) { await worker.stop(); } else { await worker.destroy(); }
Defensive patterns

Strategy: type-guard

Validate before calling

// guard before calling stop
if (typeof sandbox.stop !== 'function') {
  // fall back to destroy or surface capability limitation
}

Type guard

function supportsStop(sandbox) { return typeof sandbox === 'object' && sandbox !== null && typeof sandbox.stop === 'function'; }

Try / catch

try {
  await worker.stop();
} catch (e) {
  if (/does not support stop/.test(e.message)) {
    await worker.destroy(); // graceful stop unavailable; hard teardown
  } else throw e;
}

Prevention

When it happens

Trigger: Calling workerDeployment.stop() (e.g. from attachWorkerDeployment consumers) on a sandbox whose provider object has no stop function — checked via `if (!config.sandbox.stop)`.

Common situations: Using a sandbox provider that only supports destroy (hard teardown) but not graceful stop; custom or minimal provider implementations that omit the optional stop hook; swapping providers in config without updating lifecycle code that assumes stop exists.

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/366553e6ebfb549b. Report an issue: GitHub.

Appendix: source

Thrown at deployers/sandbox/src/worker.ts:397

  return deployment(config, executionId, info?.id ?? config.sandbox.id ?? 'unknown', info?.timeoutAt);
}

function execution(
  config: WorkerExecutionConfig,
  executionId: string,
  sandboxId: string,
  expiresAt?: Date,
): SandboxWorkerExecution {
  const resolvePaths = async () => executionPaths(await config.resolveRemoteDir(), executionId);
  return {
    sandboxId,
    executionId,
    expiresAt,
    status: options => readWorkerStatus(config.sandbox, executionId, resolvePaths, options),
    readOutput: (stream, options) => readOutput(config.sandbox, executionId, resolvePaths, stream, options),
    cancel: () => cancelExecution(config, executionId, resolvePaths),
    stop: async () => {
      if (!config.sandbox.stop) throw new Error(`Sandbox provider "${config.sandbox.provider}" does not support stop.`);
      await config.sandbox.stop();
    },
    destroy: options => destroyWithRetry(config.sandbox, options),
  };
}

function deployment(
  config: WorkerConfig,
  executionId: string,
  sandboxId: string,
  expiresAt?: Date,
): SandboxWorkerDeployment {
  return {
    ...execution(config, executionId, sandboxId, expiresAt),
    relaunch: async options => {
      if (options.executionId === executionId) throw new Error('Relaunch requires a new executionId.');
      validateInput(options.input);
      return createExecution(config, options.executionId, options.input);

View on GitHub (pinned to 75dd419e61)