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
- Filter the batch first: text_nodes = [n for n in nodes if isinstance(n, TextNode)] and run aextract on that list.
- Configure the upstream node parser to produce TextNodes only for the content destined for summary extraction.
- 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
- Filter batches to TextNode before calling aextract.
- Keep multimodal/non-text nodes on a separate pipeline branch.
- Add isinstance assertions in shared extractor utilities.
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
- Aborting parsing document; {numTags} elements found
- Command failed: {command} {result.stderr}
- Could not parse output: {output}
- llm must be a function calling LLM to use handoff
- At least one agent must be provided
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/ec434e692394d83b.
Report an issue: GitHub.