run-llama/llama_index · error · ValueError

Only `TextNode` is allowed for `Summary` extractor

Error message

Only `TextNode` is allowed for `Summary` extractor

What it means

Raised by SummaryExtractor.aextract when any node in the input batch is not a TextNode. Summary extraction runs an LLM prompt over each node's text content, and the async batch path requires every node to be a TextNode (per-node generation does tolerate non-text nodes when is_text_node_only by returning '').

Source

Thrown at llama-index-core/llama_index/core/extractors/metadata_extractors.py:427

    @classmethod
    def class_name(cls) -> str:
        return "SummaryExtractor"

    async def _agenerate_node_summary(self, node: BaseNode) -> str:
        """Generate a summary for a node."""
        if self.is_text_node_only and not isinstance(node, TextNode):
            return ""

        context_str = node.get_content(metadata_mode=self.metadata_mode)
        summary = await self.llm.apredict(
            PromptTemplate(template=self.prompt_template), context_str=context_str
        )

        return summary.strip()

    async def aextract(self, nodes: Sequence[BaseNode]) -> List[Dict]:
        if not all(isinstance(node, TextNode) for node in nodes):
            raise ValueError("Only `TextNode` is allowed for `Summary` extractor")

        node_summaries_jobs = []
        for node in nodes:
            node_summaries_jobs.append(self._agenerate_node_summary(node))

        node_summaries = await run_jobs(
            node_summaries_jobs,
            show_progress=self.show_progress,
            workers=self.num_workers,
        )

        # Extract node-level summary metadata
        metadata_list: List[Dict] = [{} for _ in nodes]
        for i, metadata in enumerate(metadata_list):
            if i > 0 and self._prev_summary and node_summaries[i - 1]:
                metadata["prev_section_summary"] = node_summaries[i - 1]
            if i < len(nodes) - 1 and self._next_summary and node_summaries[i + 1]:
                metadata["next_section_summary"] = node_summaries[i + 1]

View on GitHub (pinned to afd0fef371)

Solutions

  1. Filter the batch first: text_nodes = [n for n in nodes if isinstance(n, TextNode)] and run aextract on that list.
  2. Configure the upstream node parser to produce TextNodes only for the content destined for summary extraction.
  3. Handle non-text nodes with a separate extractor/branch appropriate to their type.

Example fix

# before
results = await summary_extractor.aextract(nodes)  # mixed node types

# after
from llama_index.core.schema import TextNode
text_nodes = [n for n in nodes if isinstance(n, TextNode)]
results = await summary_extractor.aextract(text_nodes)
Defensive patterns

Strategy: type-guard

Validate before calling

from llama_index.core.schema import TextNode

text_nodes = [n for n in nodes if isinstance(n, TextNode)]
if len(text_nodes) != len(nodes):
    logging.warning("Filtered %d non-TextNode(s) before summary extraction", len(nodes) - len(text_nodes))

Type guard

from llama_index.core.schema import TextNode, BaseNode

def all_text_nodes(nodes: list[BaseNode]) -> bool:
    return all(isinstance(n, TextNode) for n in nodes)

Prevention

When it happens

Trigger: Calling await extractor.aextract(nodes) on a list containing ImageNode, IndexNode, or a custom BaseNode subclass; mixing node types in an ingestion pipeline that feeds all parsed nodes into SummaryExtractor.

Common situations: Multimodal pipelines where image/document nodes flow alongside text; custom node classes for specialized stores; converting documents with parsers that emit non-text nodes by default.

Related errors


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