langchain-ai/deepagents · error · NotImplementedError
NotImplementedError raised by abstract `execute` (backend do
Error message
NotImplementedError raised by abstract `execute` (backend does not implement `execute`)
What it means
`SandboxBackendProtocol.execute` is the core shell-execution method of a sandbox backend; the base-class stub raises `NotImplementedError` because every concrete sandbox must implement it. Calling `execute`/`aexecute` (directly or via setup helpers like `_run_sandbox_setup`) on a subclass that didn't override it raises this error. The async wrapper only forwards `timeout` when signature introspection (`execute_accepts_timeout`) shows support, so older backend packages also fail here in related ways.
Source
Thrown at libs/deepagents/deepagents/backends/protocol.py:910
) -> ExecuteResponse:
"""Execute a shell command in the sandbox environment.
Simplified interface optimized for LLM consumption.
Args:
command: Full shell command string to execute.
timeout: Maximum time in seconds to wait for the command to complete.
If None, uses the backend's default timeout.
Callers should provide non-negative integer values for portable
behavior across backends. A value of 0 may disable timeouts on
backends that support no-timeout execution.
Returns:
`ExecuteResponse` with combined output, exit code, and truncation flag.
"""
raise NotImplementedError
async def aexecute(
self,
command: str,
*,
# ASYNC109 - timeout is a semantic parameter forwarded to the sync
# implementation, not an asyncio.timeout() contract.
timeout: int | None = None, # noqa: ASYNC109
) -> ExecuteResponse:
"""Async version of execute."""
# The middleware layer validates timeout support before calling, so
# this guard only protects direct callers bypassing the middleware.
if timeout is not None and execute_accepts_timeout(type(self)):
return await asyncio.to_thread(self.execute, command, timeout=timeout)
return await asyncio.to_thread(self.execute, command)
@lru_cache(maxsize=256)View on GitHub (pinned to a1af029e6e)
Solutions
- Implement `execute(self, command, *, timeout=None) -> ExecuteResponse` in your sandbox backend class (and have `aexecute`/inherited async path delegate to it)
- Use a concrete sandbox backend (e.g. LocalShellBackend or a partner sandbox package) instead of the protocol/base class directly
- Align package versions so the backend satisfies the current `SandboxBackendProtocol` contract including the `timeout` kwarg
- Inspect with `execute_accepts_timeout(type(backend))` before passing `timeout=` to older backends
Example fix
// before
class MySandbox(SandboxBackendProtocol):
@property
def id(self): return 'sb-1'
// after
class MySandbox(SandboxBackendProtocol):
@property
def id(self): return 'sb-1'
def execute(self, command: str, *, timeout: int | None = None) -> ExecuteResponse:
proc = subprocess.run(command, shell=True, capture_output=True, timeout=timeout)
return ExecuteResponse(output=proc.stdout + proc.stderr, exit_code=proc.returncode) Defensive patterns
Strategy: try-catch
Validate before calling
from inspect import signature
def is_executable(backend) -> bool:
fn = getattr(type(backend), 'execute', None)
if fn is SandboxBackendProtocol.execute:
return False
try:
return 'command' in signature(fn).parameters
except (TypeError, ValueError):
return False Type guard
def accepts_timeout(backend) -> bool:
return 'timeout' in signature(type(backend).execute).parameters Try / catch
try:
resp = backend.execute(cmd, timeout=30)
except NotImplementedError as e:
raise RuntimeError('backend does not support shell execution') from e Prevention
- Never instantiate SandboxBackendProtocol/BaseSandbox directly; use a concrete backend
- Implement execute with the exact signature `(self, command: str, *, timeout: int | None = None)` so async delegation and timeout introspection work
- Pin compatible deepagents/backend package versions and run protocol conformance tests in CI
When it happens
Trigger: Calling `backend.execute('ls')` on a sandbox backend subclass missing an override; running sandbox setup/tests (`_run_sandbox_setup`, setup_test_dir) against an incomplete backend; instantiating the protocol class itself instead of a concrete backend.
Common situations: Custom sandbox backends that implemented file ops but not execution; passing the abstract protocol where a concrete backend is expected; mixed deepagents/backend package versions where the backend predates the `timeout` kwarg contract.
Related errors
- NotImplementedError raised by abstract `id` property (backen
- FilesystemMiddleware does not yet support permissions with b
- enable_interpreter=True is not supported with a remote sandb
- Failed while waiting for Vercel sandbox startup.
- Missing dependencies for '{provider}' sandbox. {install_hint
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/ad596e26608b8399.
Report an issue: GitHub.