langchain-ai/deepagents · error · NotImplementedError

NotImplementedError raised by abstract `write` (backend does

Error message

NotImplementedError raised by abstract `write` (backend does not implement `write`)

What it means

The base Backend class defines `write` as an abstract method raising NotImplementedError; subclasses must implement file writing for the write tool and internal offloading. Internal callers include `_offload_tool_message_content`, `_offload_to_backend`, and `prepopulate_file` — so even read-oriented agents can trigger `write` when large tool outputs are offloaded to backend storage. Hitting this error means the configured backend cannot persist files.

Source

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

        return await asyncio.to_thread(self.glob, pattern, path)

    def write(
        self,
        file_path: str,
        content: str,
    ) -> WriteResult:
        """Write content to a file, creating it or overwriting it if it already exists.

        Args:
            file_path: Absolute path where the file should be written.

                Must start with '/'.
            content: String content to write to the file.

        Returns:
            WriteResult
        """
        raise NotImplementedError

    async def awrite(
        self,
        file_path: str,
        content: str,
    ) -> WriteResult:
        """Async version of write."""
        return await asyncio.to_thread(self.write, file_path, content)

    def edit(
        self,
        file_path: str,
        old_string: str,
        new_string: str,
        replace_all: bool = False,  # noqa: FBT001, FBT002
    ) -> EditResult:
        """Perform exact string replacements in an existing file.

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Implement `write(self, file_path, content) -> WriteResult` (paths must start with '/') in your backend subclass.
  2. If the backend is intentionally read-only, use a writable backend (e.g. StateBackend or filesystem) for offloading, or disable the write tool and offloading.
  3. Configure a composite backend: read-only source for reads plus a writable store for writes/offloads.

Example fix

// before
class ReadOnlyGitBackend(Backend):
    def read(self, file_path, offset=0, limit=2000): ...
    # agent write tool -> NotImplementedError
// after
class ReadOnlyGitBackend(Backend):
    def read(self, file_path, offset=0, limit=2000): ...
    def write(self, file_path, content):
        return WriteResult(error='backend is read-only')  # graceful, or use a writable composite
Defensive patterns

Strategy: try-catch

Validate before calling

if type(backend).write is Backend.write:
    raise RuntimeError('backend is not writable; write tool and offloading will fail')

Type guard

def supports_write(backend) -> bool:
    return type(backend).write is not Backend.write

Try / catch

try:
    backend.write(file_path, content)
except NotImplementedError:
    fallback_backend.write(file_path, content)  # e.g. StateBackend for offloads

Prevention

When it happens

Trigger: Agent write tool call routed to a read-only custom backend; large tool results auto-offloaded to a backend lacking write; direct call backend.write('/path', content) on the abstract base or partial subclass.

Common situations: Mounting a read-only or minimal backend on an agent whose tools include write; offload middleware kicking in during long-running sessions; forgetting the override during backend development.

Related errors


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