langchain-ai/deepagents · error · RuntimeError

StateBackend must be used inside a LangGraph graph execution

Error message

StateBackend must be used inside a LangGraph graph execution (e.g. via create_deep_agent). It cannot read or write state outside of a graph context. To pre-populate files, pass them on invoke: agent.invoke({"messages": [...], "files": {...}})

What it means

`StateBackend` stores agent files in the LangGraph graph state, so it can only operate while a graph node is executing with a proper `RunnableConfig` in context. `_get_config` raises this `RuntimeError` when it cannot find a config (no graph execution context), meaning `_read_files` or `_send_files_update` was called outside a graph run. The message explains the remedy: pre-populate files on `invoke`, not by calling the backend directly.

Source

Thrown at libs/deepagents/deepagents/backends/state.py:68

    def __init__(self) -> None:
        """Initialize StateBackend."""

    # ------------------------------------------------------------------
    # Internal helpers for reading / writing state via config keys
    # ------------------------------------------------------------------

    def _get_config(self) -> RunnableConfig:
        """Return the current LangGraph config, with a clear error if missing."""
        try:
            config = get_config()
        except RuntimeError:
            msg = (
                "StateBackend must be used inside a LangGraph graph execution "
                "(e.g. via create_deep_agent). It cannot read or write state "
                "outside of a graph context. To pre-populate files, pass them "
                'on invoke: agent.invoke({"messages": [...], "files": {...}})'
            )
            raise RuntimeError(msg) from None
        configurable = config.get("configurable", {})
        if CONFIG_KEY_READ not in configurable:
            msg = (
                "StateBackend requires CONFIG_KEY_READ / CONFIG_KEY_SEND in "
                "the LangGraph config. Make sure the backend is used inside "
                "a graph node or tool, not called directly. To pre-populate "
                "files, pass them on invoke: "
                'agent.invoke({"messages": [...], "files": {...}})'
            )
            raise RuntimeError(msg)
        return config

    def _read_files(self) -> dict[str, Any]:
        """Read the current `files` channel via Pregel internals.

        Uses `CONFIG_KEY_READ` to read state directly — this lets us
        initialize StateBackend once and fetch state on demand from any
        graph context (tools, middleware nodes, etc.).

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Only use StateBackend inside graph execution — build the agent with `create_deep_agent` and call `agent.invoke({'messages': [...], 'files': {...}})` to pre-populate files
  2. In tests, use the project's fake config fixtures that inject CONFIG_KEY_READ/CONFIG_KEY_SEND (see error 616) or use a standalone backend (FilesystemBackend/StoreBackend) outside graphs
  3. If you need direct file access, switch to a backend that doesn't depend on graph state
  4. Ensure async/background work runs within the graph node's context, not after it returns

Example fix

// before
backend = StateBackend()
backend.write('/a.txt', 'hello')  # RuntimeError

// after
agent = create_deep_agent(backend=StateBackend(), tools=[...])
agent.invoke({'messages': [{'role': 'user', 'content': 'hi'}], 'files': {'/a.txt': 'hello'}})
Defensive patterns

Strategy: try-catch

Validate before calling

def state_backend_usable(config) -> bool:
    return config is not None and CONFIG_KEY_READ in config.get('configurable', {}) and CONFIG_KEY_SEND in config.get('configurable', {})

Try / catch

try:
    backend.write('/a.txt', 'x')
except RuntimeError as e:
    if 'graph execution' in str(e):
        agent.invoke({'messages': [...], 'files': {'/a.txt': 'x'}})  # seed via invoke instead
    else:
        raise

Prevention

When it happens

Trigger: Instantiating `StateBackend` and calling `read`/`write`/`delete`/`ls` (which reach `_get_config` via `_read_files`/`_send_files_update`) directly in application code, outside `create_deep_agent(...).invoke(...)`; calling it from a plain script, test, or thread without a LangGraph runtime context.

Common situations: Trying to inspect or seed files before invoking the agent; unit-testing the backend without a fake graph config; background threads/callbacks that outlive the graph node and lose the config context.

Related errors


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