run-llama/llama_index · error · ValueError

Next object must be a single RelatedNodeInfo object

Error message

Next object must be a single RelatedNodeInfo object

What it means

TextNode.next_node reads relationships[NodeRelationship.NEXT] and requires an exact RelatedNodeInfo instance; anything else (dict, list, None-like substitutes) raises ValueError. NEXT is a singular, strictly-typed relationship like PREVIOUS.

Source

Thrown at llama-index-core/llama_index/core/schema.py:425

    def prev_node(self) -> Optional[RelatedNodeInfo]:
        """Prev node."""
        if NodeRelationship.PREVIOUS not in self.relationships:
            return None

        relation = self.relationships[NodeRelationship.PREVIOUS]
        if not isinstance(relation, RelatedNodeInfo):
            raise ValueError("Previous object must be a single RelatedNodeInfo object")
        return relation

    @property
    def next_node(self) -> Optional[RelatedNodeInfo]:
        """Next node."""
        if NodeRelationship.NEXT not in self.relationships:
            return None

        relation = self.relationships[NodeRelationship.NEXT]
        if not isinstance(relation, RelatedNodeInfo):
            raise ValueError("Next object must be a single RelatedNodeInfo object")
        return relation

    @property
    def parent_node(self) -> Optional[RelatedNodeInfo]:
        """Parent node."""
        if NodeRelationship.PARENT not in self.relationships:
            return None

        relation = self.relationships[NodeRelationship.PARENT]
        if not isinstance(relation, RelatedNodeInfo):
            raise ValueError("Parent object must be a single RelatedNodeInfo object")
        return relation

    @property
    def child_nodes(self) -> Optional[List[RelatedNodeInfo]]:
        """Child nodes."""
        if NodeRelationship.CHILD not in self.relationships:
            return None

View on GitHub (pinned to afd0fef371)

Solutions

  1. Use RelatedNodeInfo(node_id=...) for the NEXT relationship
  2. Let core node parsers (SentenceSplitter, HierarchicalNodeParser) build prev/next links for you
  3. If consuming external JSON, coerce relationship dicts via RelatedNodeInfo.model_validate(d)

Example fix

# before
node.relationships[NodeRelationship.NEXT] = {"node_id": next_id}

# after
node.relationships[NodeRelationship.NEXT] = RelatedNodeInfo(node_id=next_id)
Defensive patterns

Strategy: validation

Validate before calling

rel = node.relationships.get(NodeRelationship.NEXT)
if rel is not None and not isinstance(rel, RelatedNodeInfo):
    node.relationships[NodeRelationship.NEXT] = RelatedNodeInfo.model_validate(rel)

Type guard

def has_valid_next(node) -> bool:
    rel = node.relationships.get(NodeRelationship.NEXT)
    return rel is None or isinstance(rel, RelatedNodeInfo)

Prevention

When it happens

Trigger: Setting relationships[NodeRelationship.NEXT] to a plain dict or a list (e.g. when wiring sentence-window or hierarchical node chains manually), then accessing .next_node.

Common situations: Manual construction of ordered node chains instead of using SentenceSplitter/node parsers; deserializing relationship maps from JSON where NEXT became a dict.

Related errors


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