{"record":{"id":"75cca1e89ecf0eda","repo":"langchain-ai/deepagents","slug":"notimplementederror-raised-by-abstract-edit-bac","errorCode":null,"errorMessage":"NotImplementedError raised by abstract `edit` (backend does not implement `edit`)","messagePattern":"NotImplementedError raised by abstract `edit` \\(backend does not implement `edit`\\)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/backends/protocol.py","lineNumber":710,"sourceCode":"        \"\"\"Perform exact string replacements in an existing file.\n\n        Args:\n            file_path: Absolute path to the file to edit. Must start with `'/'`.\n            old_string: Exact string to search for and replace.\n\n                Must match exactly including whitespace and indentation.\n            new_string: String to replace old_string with.\n\n                Must be different from old_string.\n            replace_all: If True, replace all occurrences.\n\n                If `False` (default), `old_string` must be unique in the file or\n                the edit fails.\n\n        Returns:\n            EditResult\n        \"\"\"\n        raise NotImplementedError\n\n    async def aedit(\n        self,\n        file_path: str,\n        old_string: str,\n        new_string: str,\n        replace_all: bool = False,  # noqa: FBT001, FBT002\n    ) -> EditResult:\n        \"\"\"Async version of edit.\"\"\"\n        return await asyncio.to_thread(self.edit, file_path, old_string, new_string, replace_all)\n\n    def delete(self, file_path: str) -> DeleteResult:\n        \"\"\"Delete a path, recursively removing anything nested under it.\n\n        This method is optional. Backends that do not implement it inherit this\n        default, which raises `NotImplementedError`. Callers that need to support\n        a mix of backends should guard with\n        [`supports_delete`][deepagents.backends.protocol.supports_delete] before","sourceCodeStart":692,"sourceCodeEnd":728,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/backends/protocol.py#L692-L728","documentation":"The base Backend class defines `edit` as an abstract method raising NotImplementedError; subclasses must implement string-replacement editing to support the edit tool and backend offloading (`_offload_to_backend`). Calling `edit` on a backend without an override raises this error, meaning the backend cannot perform in-place content edits.","triggerScenarios":"Agent issues an edit tool call routed to a backend that never overrode edit; offload-to-backend flows calling edit on a partial backend; direct call backend.edit(path, old, new, replace_all=False) on the abstract base.","commonSituations":"Read-only or object-store backends attached to agents with edit enabled; custom backends that implement write but skip edit; stub backends in tests receiving model edit calls.","solutions":["Implement `edit(self, file_path, old_string, new_string, replace_all=False) -> EditResult` in your backend subclass, honoring the uniqueness requirement when replace_all is False.","If editing is unsupported, return an EditResult with an error field instead of raising, and disable the edit tool for agents using this backend.","Compose with a writable backend that supports edit for the paths that need it."],"exampleFix":"// before\nclass S3Backend(Backend):\n    def read(self, file_path, offset=0, limit=2000): ...\n    def write(self, file_path, content): ...\n// after\nclass S3Backend(Backend):\n    def read(self, file_path, offset=0, limit=2000): ...\n    def write(self, file_path, content): ...\n    def edit(self, file_path, old_string, new_string, replace_all=False):\n        text = self._load(file_path)\n        updated = text.replace(old_string, new_string) if replace_all else text.replace(old_string, new_string, 1)\n        self.write(file_path, updated)\n        return EditResult(ok=True)","handlingStrategy":"try-catch","validationCode":"if type(backend).edit is Backend.edit:\n    raise RuntimeError('backend does not implement edit; disable the edit tool or switch backends')","typeGuard":"def supports_edit(backend) -> bool:\n    return type(backend).edit is not Backend.edit","tryCatchPattern":"try:\n    result = backend.edit(file_path, old_string, new_string)\nexcept NotImplementedError:\n    content = backend.read(file_path).content\n    backend.write(file_path, content.replace(old_string, new_string, 1))","preventionTips":["Implement edit as read-modify-write if the store has no native edit support.","Honor replace_all=False uniqueness semantics; failing loudly beats silent partial edits.","Include edit in the backend capability check that runs before agent startup."],"tags":["not-implemented","abstract-method","backend-protocol"],"backgroundTag":"not-implemented","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}