run-llama/llama_index · error · ValueError
CitableBlock content must contain exactly one block when pro
Error message
CitableBlock content must contain exactly one block when provided as a list.
What it means
Raised by CitableBlock's cited_content field validator when cited_content is supplied as a list whose length is not exactly 1. The model accepts a plain str, a single block, or a one-element list (whose element may be a str); multiple blocks are ambiguous for a citation and rejected.
Source
Thrown at llama-index-core/llama_index/core/base/llms/types.py:1066
class CitationBlock(BaseRecursiveContentBlock):
"""A representation of cited content from past messages."""
block_type: Literal["citation"] = "citation"
cited_content: Annotated[
Union[TextBlock, ImageBlock], Field(discriminator="block_type")
]
source: str
title: str
additional_location_info: Dict[str, int]
@field_validator("cited_content", mode="before")
@classmethod
def validate_cited_content(cls, v: Any) -> Any:
if isinstance(v, str):
return TextBlock(text=v)
if isinstance(v, list):
if len(v) != 1:
raise ValueError(
"CitableBlock content must contain exactly one block when provided as a list."
)
value = v[0]
if isinstance(value, str):
return TextBlock(text=value)
else:
return value
return v
@classmethod
def nested_blocks_field_name(self) -> str:
return "cited_content"
def can_merge(self, other: Self) -> bool:
"""Check if this block can be merged with another block of the same type."""
# Only merge if cited_content is of the same type and is a TextBlock
if type(self.cited_content) is type(other.cited_content) and isinstance(
self.cited_content, TextBlockView on GitHub (pinned to afd0fef371)
Solutions
- Create one CitableBlock per cited passage instead of one with many blocks.
- If a list is used, ensure it has exactly one element (str or block).
- Pass a plain string when the citation is simple text: cited_content="...".
Example fix
# before
cited = CitableBlock(cited_content=[TextBlock(text=p1), TextBlock(text=p2)], source=..., title=..., additional_location_info={})
# after
cited = [
CitableBlock(cited_content=TextBlock(text=p1), source=..., title=..., additional_location_info={}),
CitableBlock(cited_content=TextBlock(text=p2), source=..., title=..., additional_location_info={}),
] Defensive patterns
Strategy: validation
Validate before calling
if isinstance(cited_content, list) and len(cited_content) != 1:
blocks = [CitableBlock(cited_content=c, source=s, title=t, additional_location_info=i) for c in cited_content] Type guard
def is_valid_cited_content(v: Any) -> bool:
return isinstance(v, str) or (isinstance(v, list) and len(v) == 1) Prevention
- Model one citation per CitableBlock.
- Unit-test citation builders against multi-passage retrieval results.
When it happens
Trigger: Constructing CitableBlock(cited_content=[TextBlock(...), TextBlock(...)]) (2+ items) or cited_content=[] (empty list); building citation objects from search hits without limiting to one block.
Common situations: Programmatically collecting multiple retrieved passages into one citation instead of creating one CitableBlock per passage; passing an empty list from a failed retrieval step.
Related errors
- Max iterations of {max_iterations} reached! Either something
- Could not format attribute {attribute_name} with value {temp
- ChatMessage contains multiple blocks, use 'ChatMessage.block
- Eval mode {eval_mode} not supported.
- Cannot specify both system_prompt and prefix_messages
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/395382817bfbbf41.
Report an issue: GitHub.