{"record":{"id":"ebb82c9333bdcf11","repo":"langchain-ai/deepagents","slug":"notimplementederror-raised-by-abstract-upload-fil","errorCode":null,"errorMessage":"NotImplementedError raised by abstract `upload_files` (backend does not implement `upload_files`)","messagePattern":"NotImplementedError raised by abstract `upload_files` \\(backend does not implement `upload_files`\\)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/backends/protocol.py","lineNumber":780,"sourceCode":"\n        Returns:\n            List of `FileUploadResponse` objects, one per input file.\n\n                Response order matches input order (`response[i] for files[i]`).\n\n                Check the error field to determine success/failure per file.\n\n        Examples:\n            ```python\n            responses = sandbox.upload_files(\n                [\n                    (\"/app/config.json\", b\"{...}\"),\n                    (\"/app/data.txt\", b\"content\"),\n                ]\n            )\n            ```\n        \"\"\"\n        raise NotImplementedError\n\n    async def aupload_files(self, files: list[tuple[str, bytes]]) -> list[FileUploadResponse]:\n        \"\"\"Async version of upload_files.\"\"\"\n        return await asyncio.to_thread(self.upload_files, files)\n\n    def download_files(self, paths: list[str]) -> list[FileDownloadResponse]:\n        \"\"\"Download multiple files from the sandbox.\n\n        This API is designed to allow developers to use it either directly or\n        by exposing it to LLMs via custom tools.\n\n        Args:\n            paths: List of file paths to download.\n\n        Returns:\n            List of `FileDownloadResponse` objects, one per input path.\n\n                Response order matches input order (`response[i] for paths[i]`).","sourceCodeStart":762,"sourceCodeEnd":798,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/backends/protocol.py#L762-L798","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nresponses = backend.upload_files([('/app/a.txt', b'hi')])\n\n// after\ndef can_upload(backend) -> bool:\n    return type(backend).upload_files is not BackendProtocol.upload_files\nif can_upload(backend):\n    responses = backend.upload_files([('/app/a.txt', b'hi')])\nelse:\n    responses = []","handlingStrategy":"validation","validationCode":"def supports_upload(backend) -> bool:\n    return type(backend).upload_files is not BackendProtocol.upload_files\n\nif not supports_upload(backend):\n    disable_media_offload = True","typeGuard":"def is_upload_capable(backend) -> bool:\n    return type(backend).upload_files is not BackendProtocol.upload_files","tryCatchPattern":"try:\n    responses = backend.upload_files(files)\nexcept NotImplementedError:\n    responses = [FileUploadResponse(path=p, error='upload unsupported') for p, _ in files]","preventionTips":["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"],"tags":["python","not-implemented","backend-protocol","file-upload"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}