{"record":{"id":"0979b75181d9c4ba","repo":"run-llama/llama_index","slug":"output-parser-must-be-pydanticoutputparser","errorCode":null,"errorMessage":"Output parser must be PydanticOutputParser.","messagePattern":"Output parser must be PydanticOutputParser\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/program/llm_program.py","lineNumber":72,"sourceCode":"        output_cls: Optional[Type[Model]] = None,\n        prompt_template_str: Optional[str] = None,\n        prompt: Optional[BasePromptTemplate] = None,\n        llm: Optional[LLM] = None,\n        verbose: bool = False,\n        **kwargs: Any,\n    ) -> \"LLMTextCompletionProgram[Model]\":\n        llm = llm or Settings.llm\n        if prompt is None and prompt_template_str is None:\n            raise ValueError(\"Must provide either prompt or prompt_template_str.\")\n        if prompt is not None and prompt_template_str is not None:\n            raise ValueError(\"Must provide either prompt or prompt_template_str.\")\n        if prompt_template_str is not None:\n            prompt = PromptTemplate(prompt_template_str)\n\n        # decide default output class if not set\n        if output_cls is None:\n            if not isinstance(output_parser, PydanticOutputParser):\n                raise ValueError(\"Output parser must be PydanticOutputParser.\")\n            output_cls = output_parser.output_cls\n        else:\n            if output_parser is None:\n                output_parser = PydanticOutputParser(output_cls=output_cls)\n\n        return cls(\n            output_parser,\n            output_cls,\n            prompt=cast(PromptTemplate, prompt),\n            llm=llm,\n            verbose=verbose,\n        )\n\n    @property\n    def output_cls(self) -> Type[Model]:\n        return self._output_cls\n\n    @property","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/program/llm_program.py#L54-L90","documentation":"When output_cls is omitted, from_defaults tries to infer the output class from output_parser.output_cls, which only exists on PydanticOutputParser. Any other BaseOutputParser subclass (or None) triggers this error. The program needs a Pydantic model class to type-check parsed results.","triggerScenarios":"Calling from_defaults(output_parser=CustomOutputParser(), prompt_template_str=...) with no output_cls, where CustomOutputParser is a plain BaseOutputParser subclass; or passing output_parser=None and no output_cls.","commonSituations":"Writing a custom output parser for non-Pydantic output; passing a plain output parser while assuming the factory infers the class; refactoring code that previously always supplied output_cls.","solutions":["Pass output_cls=YourPydanticModel explicitly; the factory then wraps it in a PydanticOutputParser for you.","Or use output_parser=PydanticOutputParser(output_cls=YourPydanticModel) so the class can be inferred.","If you truly need a custom parser, it must be a PydanticOutputParser or you must supply output_cls separately."],"exampleFix":"// before\nprogram = LLMTextCompletionProgram.from_defaults(\n    output_parser=MyCustomParser(),\n    prompt_template_str=\"...\",\n)\n// after\nprogram = LLMTextCompletionProgram.from_defaults(\n    output_parser=PydanticOutputParser(output_cls=Album),\n    prompt_template_str=\"...\",\n)","handlingStrategy":"type-guard","validationCode":"from llama_index.core.output_parsers import PydanticOutputParser\n\nif output_cls is None and not isinstance(output_parser, PydanticOutputParser):\n    raise ValueError(\"supply output_cls or a PydanticOutputParser\")","typeGuard":"from llama_index.core.output_parsers import PydanticOutputParser\n\ndef parser_has_output_cls(parser) -> bool:\n    return isinstance(parser, PydanticOutputParser) and parser.output_cls is not None","tryCatchPattern":null,"preventionTips":["Always pass output_cls explicitly in program factories; it doubles as documentation.","Keep custom output parsers for text pipelines, not Pydantic programs."],"tags":["validation","output-parser","pydantic","program"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}