langchain-ai/deepagents · error · RuntimeError

session/load requires an agent compiled with a checkpointer

Error message

session/load requires an agent compiled with a checkpointer

What it means

`_load_effective_config_data` raises `OSError` whose message is the user config's status detail (or health value) when an explicitly requested (non-default) `config.toml` exists but is unusable — typically a TOML parse error or unreadable file. On the default path it degrades to managed-only data with a warning instead, but explicit paths fail hard so callers know their config was not applied.

Source

Thrown at libs/acp/deepagents_acp/server.py:810

    def _session_config(self, session_id: str) -> RunnableConfig:
        """Build the LangGraph config and durable metadata for an ACP session."""
        metadata = {
            _ACP_SESSION_METADATA_KEY: True,
            "cwd": self._session_cwds[session_id],
        }
        if session_id in self._session_modes:
            metadata[_ACP_MODE_METADATA_KEY] = self._session_modes[session_id]
        if session_id in self._session_models:
            metadata[_ACP_MODEL_METADATA_KEY] = self._session_models[session_id]
        return {"configurable": {"thread_id": session_id}, "metadata": metadata}

    def _checkpointed_agent(self, session_id: str) -> CompiledStateGraph:
        """Return the session agent, requiring a configured checkpointer."""
        if self._agent is None or self._agent_session_id != session_id:
            self._reset_agent(session_id)
        if self._agent is None or getattr(self._agent, "checkpointer", None) is None:
            msg = "session/load requires an agent compiled with a checkpointer"
            raise RuntimeError(msg)
        return self._agent

    async def _persist_session(self, session_id: str) -> None:
        """Write the current ACP session metadata to its checkpoint thread."""
        agent = self._checkpointed_agent(session_id)
        await agent.aupdate_state(self._session_config(session_id), {}, as_node="__start__")

    async def _replay_session(
        self,
        session_id: str,
        agent: CompiledStateGraph,
    ) -> None:
        """Replay persisted conversation entries before `session/load` returns."""
        snapshots = [
            snapshot
            async for snapshot in agent.aget_state_history(self._session_config(session_id))
        ]
        messages: dict[str, Any] = {}

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Read the exception message — it contains the parser's specific complaint (line/column for TOML errors)
  2. Fix the TOML syntax at the reported line (common: unclosed quotes/brackets, duplicate keys)
  3. Verify file permissions and encoding (UTF-8) for the config file
  4. Validate the file with a TOML parser (e.g. `python -c "import tomllib; tomllib.load(open(PATH,'rb'))"`) before retrying

Example fix

# before (invalid TOML)
[models]
allowed = ["anthropic:claude-sonnet-4-5"
# after (closed bracket)
[models]
allowed = ["anthropic:claude-sonnet-4-5"]
Defensive patterns

Strategy: try-catch

Validate before calling

import tomllib
from pathlib import Path

def config_file_is_usable(path: Path) -> bool:
    try:
        tomllib.loads(path.read_text(encoding="utf-8"))
        return True
    except (OSError, UnicodeDecodeError, tomllib.TOMLDecodeError):
        return False

Type guard

def status_detail_is_readable(status: object) -> bool:
    detail = getattr(status, "detail", None)
    return bool(detail) or getattr(getattr(status, "health", None), "value", None) is not None

Try / catch

try:
    data = load_thread_config(explicit_path)
except OSError as exc:
    logger.error("config %s unusable: %s", explicit_path, exc)
    data = load_thread_config(None)  # fall back to default-path (managed-aware) read

Prevention

When it happens

Trigger: Calling `load_effort_for_model(path)`, `load_thread_config(path)`, `load_thread_columns(path)`, `load_thread_relative_time(path)`, `load_thread_sort_order(path)` (or `is_warning_suppressed`) with an explicit path to a file that fails to parse (invalid TOML, wrong encoding) or cannot be read (permissions); `detail`/`health` text from `get_config_sources(...).user.status` becomes the exception message.

Common situations: Hand-editing `config.toml` and leaving a TOML syntax error (unclosed string, bad table header); a file with invalid UTF-8; a `--config`-style flag pointing at a corrupted or permission-locked file; syncing tools writing partial files.

Related errors


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