run-llama/llama_index · error · ValueError

nodes must be a list of Node objects.

Error message

nodes must be a list of Node objects.

What it means

BaseIndex's constructor validates that every element of the nodes argument is a BaseNode instance. Documents are caught by a friendlier message (error 165); any other type (raw strings, dicts, LangChain documents, arbitrary objects) triggers this generic ValueError telling you nodes must be Node objects.

Source

Thrown at llama-index-core/llama_index/core/indices/base.py:62

        transformations: Optional[List[TransformComponent]] = None,
        show_progress: bool = False,
        **kwargs: Any,
    ) -> None:
        """Initialize with parameters."""
        if index_struct is None and nodes is None and objects is None:
            raise ValueError("One of nodes, objects, or index_struct must be provided.")
        if index_struct is not None and nodes is not None and len(nodes) >= 1:
            raise ValueError("Only one of nodes or index_struct can be provided.")
        # This is to explicitly make sure that the old UX is not used
        if nodes is not None and len(nodes) >= 1 and not isinstance(nodes[0], BaseNode):
            if isinstance(nodes[0], Document):
                raise ValueError(
                    "The constructor now takes in a list of Node objects. "
                    "Since you are passing in a list of Document objects, "
                    "please use `from_documents` instead."
                )
            else:
                raise ValueError("nodes must be a list of Node objects.")

        self._storage_context = storage_context or StorageContext.from_defaults()
        self._docstore = self._storage_context.docstore
        self._show_progress = show_progress
        self._vector_store = self._storage_context.vector_store
        self._graph_store = self._storage_context.graph_store
        self._callback_manager = callback_manager or Settings.callback_manager

        objects = objects or []
        self._object_map = {obj.index_id: obj.obj for obj in objects}
        for obj in objects:
            obj.obj = None  # clear the object to avoid serialization issues

        with self._callback_manager.as_trace("index_construction"):
            if index_struct is None:
                nodes = nodes or []
                index_struct = self.build_index_from_nodes(
                    nodes + objects,  # type: ignore

View on GitHub (pinned to afd0fef371)

Solutions

  1. Convert your items to llama-index nodes, e.g. [TextNode(text=t) for t in texts].
  2. If starting from Documents, use from_documents or a node parser (SentenceSplitter) instead of hand-building nodes.
  3. If loading persisted nodes, deserialize with the docstore (docstore.get_nodes) rather than reading JSON manually.
  4. Add an isinstance check before constructing so bad items are caught with your own context.

Example fix

# before
index = VectorStoreIndex(nodes=["chunk one", "chunk two"])  # ValueError

# after
from llama_index.core.schema import TextNode
index = VectorStoreIndex(nodes=[TextNode(text="chunk one"), TextNode(text="chunk two")])
Defensive patterns

Strategy: type-guard

Validate before calling

from llama_index.core.schema import BaseNode
bad = [i for i, n in enumerate(nodes or []) if not isinstance(n, BaseNode)]
if bad:
    raise TypeError(f"Non-node items at positions {bad}")

Type guard

def all_nodes(items) -> bool:
    return bool(items) and all(isinstance(n, BaseNode) for n in items)

Prevention

When it happens

Trigger: Passing strings, dicts, or third-party document objects in the nodes list; passing a list of Document subclasses that don't inherit BaseNode; passing a single node instead of a list of nodes where the first element is not a node.

Common situations: Interoperability code converting other frameworks' documents into llama-index without mapping to TextNode; JSON round-tripping nodes from storage and passing raw dicts; novice usage of index(nodes=[text, text]).

Related errors


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/7ad32850f4726e0d. Report an issue: GitHub.