run-llama/llama_index · error · ValueError
Failed to convert output to JSON: {output!r}
Error message
Failed to convert output to JSON: {output!r} What it means
After successfully parsing the LLM string as JSON/YAML, SelectionOutputParser normalizes a dict to a one-element list; if the parsed object is anything else (a bare string, number, or boolean), it raises ValueError('Failed to convert output to JSON: {output!r}'). The selection schema requires an array (or single object) of choice entries.
Source
Thrown at llama-index-core/llama_index/core/output_parsers/selection.py:97
# NOTE: parsing again with pyyaml
# pyyaml is less strict, and allows for trailing commas
# right now we rely on this since guidance program generates
# trailing commas
json_obj = yaml.safe_load(json_string)
except yaml.YAMLError as e_yaml:
raise OutputParserException(
f"Got invalid JSON object. Error: {e_json} {e_yaml}. "
f"Got JSON string: {json_string}"
)
except NameError as exc:
raise ImportError("Please pip install PyYAML.") from exc
if isinstance(json_obj, dict):
json_obj = [json_obj]
if not isinstance(json_obj, list):
raise ValueError(f"Failed to convert output to JSON: {output!r}")
json_output = self._format_output(json_obj)
answers = [Answer.from_dict(json_dict) for json_dict in json_output]
return StructuredOutput(raw_output=output, parsed_output=answers)
def format(self, prompt_template: str) -> str:
return prompt_template + "\n\n" + _escape_curly_braces(FORMAT_STR)
View on GitHub (pinned to afd0fef371)
Solutions
- Restore/keep the original selection prompt format string so the model emits the documented JSON array
- Pre-validate parsed output yourself if wrapping the parser: accept only dict/list, re-prompt otherwise
- Use a model with reliable instruction following for selection/routing
- Catch the ValueError (and OutputParserException) around the query call and retry with an explicit schema reminder
Example fix
# before
# model output: 'yes' -> yaml parses to bool True -> ValueError: Failed to convert output to JSON
response = selector.select(options)
# after
from llama_index.core.output_parsers import OutputParserException
try:
response = selector.select(options)
except (OutputParserException, ValueError):
response = selector.select(options, prompt_extra="Respond ONLY as a JSON array per the schema.") Defensive patterns
Strategy: validation
Validate before calling
import json
obj = json.loads(llm_output) # or yaml.safe_load
if not isinstance(obj, (dict, list)):
raise ValueError(f"selection output is a scalar ({obj!r}); re-prompt for JSON array") Type guard
def is_selection_shape(obj) -> bool:
return isinstance(obj, (dict, list)) and (not isinstance(obj, list) or all(isinstance(i, dict) for i in obj)) Try / catch
try:
result = selector.select(prompt)
except ValueError as e:
if "Failed to convert output to JSON" in str(e):
result = selector.select(prompt, prompt_extra="Return ONLY the JSON array per the schema.")
else:
raise Prevention
- Keep the stock selection FORMAT_STR prompt so models emit the JSON array
- Catch both ValueError and OutputParserException around selection calls and re-prompt once
- Test selection prompts against your weakest supported model
When it happens
Trigger: Model returns a plain string like '"Paris"' or a number (e.g. via yaml fallback parsing 'yes'/'42'), or a YAML scalar ('answer' parses as the string 'answer') instead of the expected [{answer: ..., score: ...}] structure; also markdown-fenced content where the outer parse yields a scalar.
Common situations: Prompts where the model replies with just the choice text instead of the JSON structure; selection templates modified/customized so the FORMAT_STR contract is broken; very small models echoing the query.
Related errors
- Got invalid JSON object. Error: {e_json} {e_yaml}. Got JSON
- Failed to parse pydantic object from guidance program. Proba
- Got empty streaming response
- Expected ActionReasoningStep, got {reasoning_step}
- LLM only supports text inputs
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/766980eaf6f53562.
Report an issue: GitHub.