langchain-ai/deepagents · error · NotImplementedError
NotImplementedError raised by abstract `upload_files` (backe
Error message
NotImplementedError raised by abstract `upload_files` (backend does not implement `upload_files`)
What it means
`BackendProtocol.upload_files` is an optional bulk-upload capability with a base stub that raises `NotImplementedError`. Only sandbox-style backends implement it. If a caller (directly, or via `_offload_inline_media` when large media outputs are offloaded to the sandbox) invokes it on a backend that never overrode the method, this error is raised.
Source
Thrown at libs/deepagents/deepagents/backends/protocol.py:780
Returns:
List of `FileUploadResponse` objects, one per input file.
Response order matches input order (`response[i] for files[i]`).
Check the error field to determine success/failure per file.
Examples:
```python
responses = sandbox.upload_files(
[
("/app/config.json", b"{...}"),
("/app/data.txt", b"content"),
]
)
```
"""
raise NotImplementedError
async def aupload_files(self, files: list[tuple[str, bytes]]) -> list[FileUploadResponse]:
"""Async version of upload_files."""
return await asyncio.to_thread(self.upload_files, files)
def download_files(self, paths: list[str]) -> list[FileDownloadResponse]:
"""Download multiple files from the sandbox.
This API is designed to allow developers to use it either directly or
by exposing it to LLMs via custom tools.
Args:
paths: List of file paths to download.
Returns:
List of `FileDownloadResponse` objects, one per input path.
Response order matches input order (`response[i] for paths[i]`).View on GitHub (pinned to a1af029e6e)
Solutions
- Use a backend that implements `upload_files` (e.g. a sandbox backend like LocalShellBackend)
- Guard with a capability check before offloading: verify `type(backend).upload_files is not BackendProtocol.upload_files`
- Catch NotImplementedError around upload/offload paths and disable inline-media offloading in that case
- Override `upload_files` in your custom backend
Example fix
// before
responses = backend.upload_files([('/app/a.txt', b'hi')])
// after
def can_upload(backend) -> bool:
return type(backend).upload_files is not BackendProtocol.upload_files
if can_upload(backend):
responses = backend.upload_files([('/app/a.txt', b'hi')])
else:
responses = [] Defensive patterns
Strategy: validation
Validate before calling
def supports_upload(backend) -> bool:
return type(backend).upload_files is not BackendProtocol.upload_files
if not supports_upload(backend):
disable_media_offload = True Type guard
def is_upload_capable(backend) -> bool:
return type(backend).upload_files is not BackendProtocol.upload_files Try / catch
try:
responses = backend.upload_files(files)
except NotImplementedError:
responses = [FileUploadResponse(path=p, error='upload unsupported') for p, _ in files] Prevention
- Check upload capability before enabling inline-media offloading features
- Prefer sandbox backends when your workflow needs bulk file transfer
- Keep custom backend subclasses in sync with the protocol by running the protocol conformance tests
When it happens
Trigger: Calling `backend.upload_files([(path, bytes), ...])` or `aupload_files` on a backend lacking an override; running media-output offloading (`_offload_inline_media`) against a backend without upload support.
Common situations: Using a state or composite backend where the user expected sandbox-style uploads; custom backend subclasses that implemented `execute`/`read` but not the bulk file APIs; backend swapped by configuration without checking capabilities.
Related errors
- NotImplementedError raised by abstract `delete` (backend doe
- NotImplementedError raised by abstract `download_files` (bac
- NotImplementedError raised by abstract `ls` (backend does no
- NotImplementedError raised by abstract `read` (backend does
- NotImplementedError raised by abstract `grep` (backend does
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/ebb82c9333bdcf11.
Report an issue: GitHub.