run-llama/llama_index · error · ValueError
There are {len(self.reasons)} selections, please use .reason
Error message
There are {len(self.reasons)} selections, please use .reasons. What it means
Raised by SelectorResult.reason when a multi-selection selector result holds more than (or fewer than) exactly one selection. The single-value accessor .reason only works when len(self.selections) == 1; for multi-choice routing you must read the list property .reasons instead. Note the message says '.reasons' while the sibling property .ind tells you to use .inds' plural accessors.
Source
Thrown at llama-index-core/llama_index/core/base/base_selector.py:36
class MultiSelection(BaseModel):
"""A multi-selection of choices."""
selections: List[SingleSelection]
@property
def ind(self) -> int:
if len(self.selections) != 1:
raise ValueError(
f"There are {len(self.selections)} selections, please use .inds."
)
return self.selections[0].index
@property
def reason(self) -> str:
if len(self.reasons) != 1:
raise ValueError(
f"There are {len(self.reasons)} selections, please use .reasons."
)
return self.selections[0].reason
@property
def inds(self) -> List[int]:
return [x.index for x in self.selections]
@property
def reasons(self) -> List[str]:
return [x.reason for x in self.selections]
# separate name for clarity and to not confuse function calling model
SelectorResult = MultiSelection
def _wrap_choice(choice: MetadataType) -> ToolMetadata:View on GitHub (pinned to afd0fef371)
Solutions
- If you expect multiple selections, read selector_result.reasons (list of str) and selector_result.inds (list of int) instead of .reason/.ind.
- If you expect exactly one selection, switch the selector to a single selector (e.g. PydanticSingleSelector or LLMSingleSelector) so only one selection is produced.
- Inspect len(selector_result.selections) before choosing the accessor and branch accordingly.
Example fix
// before
sel = await selector.select(choices, query)
reason = sel.reason # ValueError if multiple selections
// after
sel = await selector.select(choices, query)
if len(sel.selections) == 1:
reason = sel.reason
else:
reasons = sel.reasons # List[str] Defensive patterns
Strategy: type-guard
Validate before calling
result = selector.select(choices, query)
if len(result.selections) != 1:
reasons = result.reasons
inds = result.inds
else:
reason, ind = result.reason, result.ind Type guard
def is_single_selection(r: SelectorResult) -> bool:
return len(r.selections) == 1 Try / catch
try:
reason = result.reason
except ValueError:
reason = result.reasons # fall back to list accessor Prevention
- Always branch on len(result.selections) before using singular accessors.
- Match your selector class (single vs multi) to how you read results.
When it happens
Trigger: Calling selector_result.reason after a selector (e.g. PydanticSingleSelector vs PydanticMultiSelector) ran with multiple choices, or when the LLM returned multiple JSON selections. Any .select() call over >1 choices using a multi-selector returns a MultiSelection where len(selections) != 1.
Common situations: Switching a router/query engine from a single-selector to a multi-selector (e.g. RouterQueryEngine with selector_type=PydanticMultiSelector) but still reading .reason/.ind; LLM emitting several selections for a single-choice prompt.
Related errors
- Unexpected type: {type(choice)}
- Unexpected type: {type(query)}
- Failed to select query engine
- Failed to select retriever
- First argument to Readability constructor should be a docume
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/77894865c5ee4de0.
Report an issue: GitHub.