run-llama/llama_index · error · ValueError
IndexNode obj is not serializable: {obj}
Error message
IndexNode obj is not serializable: {obj} What it means
IndexNode can wrap an arbitrary Python object in its obj field (used by recursive retrieval over agents, query engines, retrievers). When serializing, _serialize_obj tries doc_to_json for BaseNode, model_dump for pydantic BaseModel, and json.dumps for everything else; if all fail it raises ValueError('IndexNode obj is not serializable').
Source
Thrown at llama-index-core/llama_index/core/schema.py:975
"""
index_id: str
obj: Any = None
def _serialize_obj(self) -> Any:
from llama_index.core.storage.docstore.utils import doc_to_json
try:
if self.obj is None:
return None
elif isinstance(self.obj, BaseNode):
return doc_to_json(self.obj)
elif isinstance(self.obj, BaseModel):
return self.obj.model_dump()
else:
return json.dumps(self.obj)
except Exception:
raise ValueError("IndexNode obj is not serializable: " + str(self.obj))
@model_serializer(mode="wrap")
def custom_model_dump(
self, handler: SerializerFunctionWrapHandler, info: SerializationInfo
) -> Dict[str, Any]:
data = super().custom_model_dump(handler, info)
data["obj"] = self._serialize_obj()
return data
def dict(self, **kwargs: Any) -> Dict[str, Any]:
data = super().dict(**kwargs)
data["obj"] = self._serialize_obj()
return data
@classmethod
def from_text_node(
cls,
node: TextNode,View on GitHub (pinned to afd0fef371)
Solutions
- Wrap the object in a pydantic BaseModel (or make it a dataclass supporting json.dumps) so one of the three serialization branches succeeds
- Store a serializable reference (id/string/config) in obj and keep the live object in an object_map instead
- Set obj=None for nodes that only need to exist as index structure
Example fix
# before
index_node = IndexNode(text="router", obj=my_retriever) # not serializable
# after
from pydantic import BaseModel
class RetrieverRef(BaseModel):
retriever_name: str
index_node = IndexNode(text="router", obj=RetrieverRef(retriever_name="base"))
# live retriever stays in the object_map / recursive_retriever mapping Defensive patterns
Strategy: validation
Validate before calling
import json
from pydantic import BaseModel
def obj_is_serializable(obj) -> bool:
if obj is None or isinstance(obj, (BaseNode, BaseModel)):
return True
try:
json.dumps(obj)
return True
except (TypeError, ValueError):
return False Type guard
def index_node_safe_to_persist(n: "IndexNode") -> bool:
return obj_is_serializable(n.obj) Prevention
- Keep live objects in object_map, serializable refs in obj
- Wrap third-party objects in a pydantic model before attaching
- Persist only ref ids and rehydrate objects at load time
When it happens
Trigger: Creating IndexNode(obj=<non-serializable object>) — e.g. a raw retriever/query engine instance, a lambda, or an object holding open connections — and then persisting it (docstore.save, json()/model_dump, storage context persist).
Common situations: Recursive/agent retrieval where obj holds live objects; calling index.storage_context.persist() with object-bearing IndexNodes in the docstore; deep-copy or caching layers that serialize the node.
Related errors
- Object {obj} is not retrievable.
- First argument to Readability constructor should be a docume
- Command failed: {command} {result.stderr}
- Must provide either user_msg or chat_history
- Embedding loading requires a class_name
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/4c29d1b582928303.
Report an issue: GitHub.