{"record":{"id":"b0b73ce8efc70d63","repo":"langchain-ai/deepagents","slug":"notimplementederror-raised-by-abstract-id-proper","errorCode":null,"errorMessage":"NotImplementedError raised by abstract `id` property (backend does not implement `id`)","messagePattern":"NotImplementedError raised by abstract `id` property \\(backend does not implement `id`\\)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/backends/protocol.py","lineNumber":885,"sourceCode":"    \"\"\"The command result. `response.truncated` indicates the output hit the size cap.\"\"\"\n\n\nclass SandboxBackendProtocol(BackendProtocol):\n    \"\"\"Extension of `BackendProtocol` that adds shell command execution.\n\n    Designed for backends running in isolated environments (containers, VMs,\n    remote hosts).\n\n    Adds `execute()`/`aexecute()` for shell commands and an `id` property.\n\n    See `BaseSandbox` for a base class that implements all inherited file\n    operations by delegating to `execute()`.\n    \"\"\"\n\n    @property\n    def id(self) -> str:\n        \"\"\"Unique identifier for the sandbox backend instance.\"\"\"\n        raise NotImplementedError\n\n    def execute(\n        self,\n        command: str,\n        *,\n        timeout: int | None = None,\n    ) -> ExecuteResponse:\n        \"\"\"Execute a shell command in the sandbox environment.\n\n        Simplified interface optimized for LLM consumption.\n\n        Args:\n            command: Full shell command string to execute.\n            timeout: Maximum time in seconds to wait for the command to complete.\n\n                If None, uses the backend's default timeout.\n\n                Callers should provide non-negative integer values for portable","sourceCodeStart":867,"sourceCodeEnd":903,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/backends/protocol.py#L867-L903","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Define an `id` property returning a stable unique string in your sandbox backend class","For per-instance identity, generate an id in `__init__` (e.g. uuid4 hex or container id) and return it from the property","Prefer subclassing `BaseSandbox` and filling in required members per its docs","Catch AttributeError/NotImplementedError in generic code that displays backend ids"],"exampleFix":"// before\nclass MySandbox(SandboxBackendProtocol):\n    def execute(self, command, *, timeout=None): ...\n\n// after\nclass MySandbox(SandboxBackendProtocol):\n    def __init__(self):\n        self._id = uuid.uuid4().hex\n\n    @property\n    def id(self) -> str:\n        return self._id\n\n    def execute(self, command, *, timeout=None): ...","handlingStrategy":"validation","validationCode":"def has_sandbox_id(backend) -> bool:\n    return isinstance(getattr(type(backend), 'id', None), property) and \\\n        type(backend).id.fget is not SandboxBackendProtocol.id.fget\n\n# or at runtime:\ntry:\n    sid = backend.id\nexcept NotImplementedError:\n    sid = None","typeGuard":"def is_concrete_sandbox(backend) -> bool:\n    try:\n        return isinstance(backend.id, str) and bool(backend.id)\n    except NotImplementedError:\n        return False","tryCatchPattern":"try:\n    sid = backend.id\nexcept NotImplementedError:\n    raise RuntimeError(f'{type(backend).__name__} must define the id property') from None","preventionTips":["Always implement the `id` property when subclassing SandboxBackendProtocol — it is mandatory, unlike file ops","Generate per-instance ids in `__init__` (uuid4 or container id)","Add an instantiation smoke test that reads `backend.id` for every sandbox backend"],"tags":["python","not-implemented","sandbox","abstract-property"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}