{"record":{"id":"b3251f723ac9d587","repo":"run-llama/llama_index","slug":"got-invalid-json-object-error-e-json-e-yaml","errorCode":null,"errorMessage":"Got invalid JSON object. Error: {e_json} {e_yaml}. Got JSON string: {json_string}","messagePattern":"Got invalid JSON object\\. Error: (.+?) (.+?)\\. Got JSON string: (.+?)","errorType":"exception","errorClass":"OutputParserException","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/output_parsers/selection.py","lineNumber":86,"sourceCode":"            output_json.append(json_dict)\n\n        return output_json\n\n    def parse(self, output: str) -> Any:\n        json_string = _marshal_llm_to_json(output)\n        try:\n            json_obj = json.loads(json_string)\n        except json.JSONDecodeError as e_json:\n            try:\n                import yaml\n\n                # NOTE: parsing again with pyyaml\n                #       pyyaml is less strict, and allows for trailing commas\n                #       right now we rely on this since guidance program generates\n                #       trailing commas\n                json_obj = yaml.safe_load(json_string)\n            except yaml.YAMLError as e_yaml:\n                raise OutputParserException(\n                    f\"Got invalid JSON object. Error: {e_json} {e_yaml}. \"\n                    f\"Got JSON string: {json_string}\"\n                )\n            except NameError as exc:\n                raise ImportError(\"Please pip install PyYAML.\") from exc\n\n        if isinstance(json_obj, dict):\n            json_obj = [json_obj]\n\n        if not isinstance(json_obj, list):\n            raise ValueError(f\"Failed to convert output to JSON: {output!r}\")\n\n        json_output = self._format_output(json_obj)\n        answers = [Answer.from_dict(json_dict) for json_dict in json_output]\n        return StructuredOutput(raw_output=output, parsed_output=answers)\n\n    def format(self, prompt_template: str) -> str:\n        return prompt_template + \"\\n\\n\" + _escape_curly_braces(FORMAT_STR)","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/output_parsers/selection.py#L68-L104","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"# before\nresponse = router_query_engine.query(\"What is 2+2?\")  # OutputParserException: invalid JSON/YAML\n\n# after\nfrom llama_index.core.output_parsers import OutputParserException\ntry:\n    response = router_query_engine.query(\"What is 2+2?\")\nexcept OutputParserException:\n    response = router_query_engine.query(\"Answer using the required JSON schema exactly.\")","handlingStrategy":"retry","validationCode":"import json\ndef is_parseable_selection_output(s: str) -> bool:\n    try:\n        json.loads(s)\n        return True\n    except json.JSONDecodeError:\n        try:\n            import yaml\n            obj = yaml.safe_load(s)\n            return isinstance(obj, (dict, list))\n        except Exception:\n            return False","typeGuard":null,"tryCatchPattern":"from llama_index.core.output_parsers import OutputParserException\nfor attempt in range(2):\n    try:\n        result = selector.select(prompt)\n        break\n    except OutputParserException as e:\n        if attempt == 1:\n            raise\n        prompt = prompt + \"\\nRespond ONLY with valid JSON (no prose, no trailing commas beyond YAML tolerance).\"","preventionTips":["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"],"tags":["llm","output-parsing","json","yaml","routing"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}