run-llama/llama_index · error · OutputParserException
Got invalid JSON object. Error: {e_json} {e_yaml}. Got JSON
Error message
Got invalid JSON object. Error: {e_json} {e_yaml}. Got JSON string: {json_string} What it means
SelectionOutputParser.parse (used for LLM selection/routing output) first tries json.loads on the LLM string, then falls back to yaml.safe_load (which tolerates trailing commas). Only when BOTH parsers fail does it raise OutputParserException embedding both error messages and the offending string — i.e. the model's output was neither valid JSON nor YAML.
Source
Thrown at llama-index-core/llama_index/core/output_parsers/selection.py:86
output_json.append(json_dict)
return output_json
def parse(self, output: str) -> Any:
json_string = _marshal_llm_to_json(output)
try:
json_obj = json.loads(json_string)
except json.JSONDecodeError as e_json:
try:
import yaml
# 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
- Catch OutputParserException and retry the query or re-ask with a stricter instruction
- Raise max_tokens/num_output so the selection payload is never truncated
- Use a stronger model or structured-output-capable model for routing/selection
- Sanitize model output before parsing (strip markdown fences, smart quotes) via a pre-processing wrapper
Example fix
# before
response = router_query_engine.query("What is 2+2?") # OutputParserException: invalid JSON/YAML
# after
from llama_index.core.output_parsers import OutputParserException
try:
response = router_query_engine.query("What is 2+2?")
except OutputParserException:
response = router_query_engine.query("Answer using the required JSON schema exactly.") Defensive patterns
Strategy: retry
Validate before calling
import json
def is_parseable_selection_output(s: str) -> bool:
try:
json.loads(s)
return True
except json.JSONDecodeError:
try:
import yaml
obj = yaml.safe_load(s)
return isinstance(obj, (dict, list))
except Exception:
return False Try / catch
from llama_index.core.output_parsers import OutputParserException
for attempt in range(2):
try:
result = selector.select(prompt)
break
except OutputParserException as e:
if attempt == 1:
raise
prompt = prompt + "\nRespond ONLY with valid JSON (no prose, no trailing commas beyond YAML tolerance)." Prevention
- Set max_tokens generously for selection outputs to avoid truncation
- Prefer models with reliable JSON formatting for routing
- Strip markdown fences and normalize quotes from LLM output before it reaches the parser
When it happens
Trigger: An LLM (via RouterQueryEngine/selection prompting) returning output with unterminated strings, smart quotes, unescaped newlines in values, markdown fences mixed with truncation, or truncated output exceeding max_tokens; also any string that is invalid in both grammars (e.g. a bare sentence with a colon, YAML may still parse — truly invalid: unbalanced brackets).
Common situations: Weaker/open models producing malformed selection JSON; max_tokens too small so choices array is cut off; prompts altered so the model answers in prose; tool descriptions containing braces that confuse the model's formatting.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to convert output to JSON: {output!r}
- Please pip install PyYAML.
- Failed to parse pydantic object from guidance program. Proba
- Got empty streaming response
- Expected ActionReasoningStep, got {reasoning_step}
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/b3251f723ac9d587.
Report an issue: GitHub.