langchain-ai/deepagents · error · NotImplementedError

NotImplementedError raised by abstract `id` property (backen

Error message

NotImplementedError raised by abstract `id` property (backend does not implement `id`)

What it means

`SandboxBackendProtocol.id` is an abstract property: every sandbox backend must supply a unique identifier for the sandbox instance, and the base class raises `NotImplementedError` to enforce this. It fires when a `SandboxBackendProtocol` subclass is instantiated and its `id` is read without an override — note that unlike optional file APIs, `id` is mandatory for sandbox backends.

Source

Thrown at libs/deepagents/deepagents/backends/protocol.py:885

    """The command result. `response.truncated` indicates the output hit the size cap."""


class SandboxBackendProtocol(BackendProtocol):
    """Extension of `BackendProtocol` that adds shell command execution.

    Designed for backends running in isolated environments (containers, VMs,
    remote hosts).

    Adds `execute()`/`aexecute()` for shell commands and an `id` property.

    See `BaseSandbox` for a base class that implements all inherited file
    operations by delegating to `execute()`.
    """

    @property
    def id(self) -> str:
        """Unique identifier for the sandbox backend instance."""
        raise NotImplementedError

    def execute(
        self,
        command: str,
        *,
        timeout: int | None = None,
    ) -> 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

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Define an `id` property returning a stable unique string in your sandbox backend class
  2. For per-instance identity, generate an id in `__init__` (e.g. uuid4 hex or container id) and return it from the property
  3. Prefer subclassing `BaseSandbox` and filling in required members per its docs
  4. Catch AttributeError/NotImplementedError in generic code that displays backend ids

Example fix

// before
class MySandbox(SandboxBackendProtocol):
    def execute(self, command, *, timeout=None): ...

// after
class MySandbox(SandboxBackendProtocol):
    def __init__(self):
        self._id = uuid.uuid4().hex

    @property
    def id(self) -> str:
        return self._id

    def execute(self, command, *, timeout=None): ...
Defensive patterns

Strategy: validation

Validate before calling

def has_sandbox_id(backend) -> bool:
    return isinstance(getattr(type(backend), 'id', None), property) and \
        type(backend).id.fget is not SandboxBackendProtocol.id.fget

# or at runtime:
try:
    sid = backend.id
except NotImplementedError:
    sid = None

Type guard

def is_concrete_sandbox(backend) -> bool:
    try:
        return isinstance(backend.id, str) and bool(backend.id)
    except NotImplementedError:
        return False

Try / catch

try:
    sid = backend.id
except NotImplementedError:
    raise RuntimeError(f'{type(backend).__name__} must define the id property') from None

Prevention

When it happens

Trigger: Reading `backend.id` on a class that subclasses `SandboxBackendProtocol` (or `BaseSandbox`) but does not define the `id` property; instantiating an incomplete custom sandbox backend and passing it to middleware that logs or routes by id.

Common situations: Hand-rolling a sandbox backend for a container/VM platform and forgetting the `id` property; partially migrating a backend class; tests constructing bare protocol instances.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/b0b73ce8efc70d63. Report an issue: GitHub.