langchain-ai/deepagents · error · TypeError
LangGraph returned non-object thread state.
Error message
LangGraph returned non-object thread state.
What it means
After fetching thread state, the SDK expects LangGraph's `get_state` values to be an object (dict). If the server returns any other shape — null, a list, or a scalar — _hydrate_state raises this TypeError rather than crashing later with an opaque attribute error. This usually signals a server/runtime mismatch or corrupted thread state rather than a problem with your request.
Source
Thrown at libs/code/deepagents_code/offload_api.py:552
{str(key): value for key, value in responses.items()},
)
def _hydrate_state(values: object) -> _OffloadState:
"""Hydrate serialized checkpoint messages for the compaction service.
Args:
values: State values returned by LangGraph Server.
Returns:
A shallow state copy containing LangChain message objects.
Raises:
TypeError: If the server returns an unexpected state shape.
"""
if not isinstance(values, dict):
msg = "LangGraph returned non-object thread state."
raise TypeError(msg)
state = dict(values)
messages = state.get("messages", [])
if not isinstance(messages, list):
msg = "LangGraph returned a non-list messages channel."
raise TypeError(msg)
state["messages"] = convert_to_messages(messages)
# LangGraph serializes the summary stored inside the private event channel
# independently of the top-level `messages` channel. The summarization SDK
# prepends it to the effective conversation, so it must be a message object
# too rather than the serialized dict returned by the thread API.
event = state.get("_summarization_event")
if isinstance(event, Mapping) and "summary_message" in event:
hydrated_event = dict(event)
summary_message = hydrated_event["summary_message"]
hydrated_event["summary_message"] = convert_to_messages([summary_message])[0]
state["_summarization_event"] = hydrated_event
return cast("_OffloadState", state)View on GitHub (pinned to a1af029e6e)
Solutions
- Verify the thread server version matches the SDK's expected LangGraph threads API; upgrade the server or pin the SDK accordingly.
- Confirm the thread_id exists (client.threads.get(thread_id)) before offloading; recreate the thread if its state is missing.
- Catch TypeError around the offload call and surface 'unreadable thread state' to the user instead of retrying blindly.
- Inspect the raw get_state response (log it) to see what shape is actually returned; check for proxies rewriting the body.
Example fix
// before
state = await offload(thread_id, payload)
// after
try:
state = await offload(thread_id, payload)
except TypeError as exc:
if "non-object thread state" in str(exc):
raise RuntimeError(f"Thread {thread_id} state is unreadable; recreate the thread") from exc
raise Defensive patterns
Strategy: try-catch
Validate before calling
before = await client.threads.get_state(thread_id)
if not isinstance(before, dict):
raise RuntimeError(f"Thread {thread_id} returned non-object state; server/schema mismatch") Type guard
def is_thread_state(values) -> bool:
return isinstance(values, dict) Try / catch
try:
state = await offload(thread_id, payload)
except TypeError as exc:
if "non-object thread state" in str(exc):
raise RuntimeError(
f"Thread {thread_id} state is unreadable; verify server version or recreate the thread"
) from exc
raise Prevention
- Pin the thread server and SDK to compatible LangGraph versions
- Confirm the thread exists before offloading (client.threads.get)
- Log raw get_state responses once when integrating a new server/proxy
- Do not retry blindly on this error — it is deterministic, not transient
When it happens
Trigger: _execute_offload calling client.threads.get_state(thread_id) and receiving values that is not a dict (None from an empty/unknown thread, a list, or a differently shaped payload from an incompatible server version).
Common situations: Pointing the client at an older/incompatible LangGraph thread server whose state schema differs, a thread id that exists but has no object-shaped state, proxy/gateway mangling the response body, or a mocked client in tests returning a non-dict.
Related errors
- LangGraph returned a non-list messages channel.
- -32002
- SHELL_ALLOW_ALL should not be used with ShellAllowListMiddle
- interpreter_ptc must be False, 'safe', 'all', or a list of t
- --model-params must be a JSON object, got {type}
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/7e8a93e57396c3f3.
Report an issue: GitHub.