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
- Only use StateBackend inside graph execution — build the agent with `create_deep_agent` and call `agent.invoke({'messages': [...], 'files': {...}})` to pre-populate files
- 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
- If you need direct file access, switch to a backend that doesn't depend on graph state
- 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
- Never call StateBackend from application code; route all file access through agent tools
- Seed files with `agent.invoke({'messages': [...], 'files': {...}})`
- Use FilesystemBackend or StoreBackend when you need file I/O outside a graph run
- Keep background/async work inside the graph node so the config context stays available
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
- StateBackend requires CONFIG_KEY_READ / CONFIG_KEY_SEND in t
- shell.allow_list is missing from the configuration manifest
- Async subagent '{name}' has no url configured. ASGI transpor
- Failed to get run status: {e}
- Failed to cancel run: {e}
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/aaa75d342012cf29.
Report an issue: GitHub.