langchain-ai/deepagents · error · RuntimeError

archive read failed for

Error message

archive read failed for {path}: {response.error}

What it means

When reading the archive snapshot, any backend-reported error other than FILE_NOT_FOUND is fatal: `_previous_content` raises RuntimeError embedding the path and the backend's error string. The offload write path refuses to continue because it cannot establish the prior archive content needed for a safe append/rollback.

Solutions

  1. Read the backend error in the message and fix the underlying cause (credentials, network, permissions).
  2. Retry the offload once connectivity is restored — the write aborted before mutating state.
  3. Verify the archive backend is healthy and the archive path exists/is readable.

Example fix

// check before offloading
resp = await backend.adownload_files([archive_path])
if resp and resp[0].error not in (None, FILE_NOT_FOUND):
    raise RuntimeError(f"archive unavailable: {resp[0].error}")  # fix credentials/network first
Defensive patterns

Strategy: retry

Validate before calling

resp = (await backend.adownload_files([path]) or [None])[0]
if resp is not None and resp.error not in (None, FILE_NOT_FOUND):
    raise ArchiveUnavailable(f"precheck failed for {path}: {resp.error}")

Type guard

def is_readable(resp: FileDownloadResponse | None) -> bool:
    return resp is not None and resp.error in (None, FILE_NOT_FOUND)

Try / catch

try:
    await offload(thread_id)
except RuntimeError as e:
    if "archive read failed" in str(e):
        await refresh_backend_credentials()
        await offload(thread_id)  # safe: write aborted before mutating state
    else:
        raise

Prevention

When it happens

Trigger: `adownload_files` returns a response with a non-FILE_NOT_FOUND `error` (permission denied, timeout, deserialization failure, corrupted record) while a `/offload` write appends staged messages.

Common situations: Expired cloud-storage credentials; network partition between server and archive store; archive file corrupted or locked by another process; wrong archive path configuration pointing at inaccessible locations.

Related errors


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

Appendix: source

Thrown at libs/code/deepagents_code/offload_middleware.py:577

    async def _previous_content(self, path: str) -> tuple[bool, str]:
        """Read the archive snapshot needed to undo an uncommitted append.

        Returns:
            Whether the archive existed and its prior UTF-8 content.

        Raises:
            RuntimeError: If the backend cannot return the archive snapshot.
        """
        responses = await self.backend.adownload_files([path])
        if not responses:
            msg = f"archive backend returned no response for {path}"
            raise RuntimeError(msg)
        response = responses[0]
        if response.error == FILE_NOT_FOUND:
            return False, ""
        if response.error is not None:
            msg = f"archive read failed for {path}: {response.error}"
            raise RuntimeError(msg)
        content = response.content or b""
        return True, content.decode("utf-8")

    async def write(self) -> _ArchiveAppend | None:
        """Append staged messages and retain enough state for rollback.

        Returns:
            The reversible append, or `None` when the SDK could not write it.
        """
        path = self.summarization._get_history_path(self.session_id)
        existed, previous = await self._previous_content(path)
        guard = cast("BackendProtocol", _ArchiveReadGuard(self.backend))
        written_path = await self.summarization._aoffload_to_backend(
            guard, self.messages, self.session_id
        )
        append = _ArchiveAppend(self.backend, path, existed, previous)
        if written_path is None:
            await append.rollback()

View on GitHub (pinned to a1af029e6e)