{"record":{"id":"0fabdcec5b6530d6","repo":"langchain-ai/langchain","slug":"runnable-self-class-name-doesn-t-have-an","errorCode":null,"errorMessage":"Runnable {self.__class__.__name__} doesn't have an inferable OutputType. Override the OutputType property to specify the output type.","messagePattern":"Runnable (.+?) doesn't have an inferable OutputType\\. Override the OutputType property to specify the output type\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/output_parsers/base.py","lineNumber":201,"sourceCode":"    def OutputType(self) -> type[T]:\n        \"\"\"Return the output type for the parser.\n\n        This property is inferred from the first type argument of the class.\n\n        Raises:\n            TypeError: If the class doesn't have an inferable `OutputType`.\n        \"\"\"\n        for base in self.__class__.mro():\n            if hasattr(base, \"__pydantic_generic_metadata__\"):\n                metadata = base.__pydantic_generic_metadata__\n                if \"args\" in metadata and len(metadata[\"args\"]) > 0:\n                    return cast(\"type[T]\", metadata[\"args\"][0])\n\n        msg = (\n            f\"Runnable {self.__class__.__name__} doesn't have an inferable OutputType. \"\n            \"Override the OutputType property to specify the output type.\"\n        )\n        raise TypeError(msg)\n\n    @override\n    def invoke(\n        self,\n        input: str | BaseMessage,\n        config: RunnableConfig | None = None,\n        **kwargs: Any,\n    ) -> T:\n        if isinstance(input, BaseMessage):\n            return self._call_with_config(\n                lambda inner_input: self.parse_result(\n                    [ChatGeneration(message=inner_input)]\n                ),\n                input,\n                config,\n                run_type=\"parser\",\n            )\n        return self._call_with_config(","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/output_parsers/base.py#L183-L219","documentation":"`BaseOutputParser.Type` is inferred from the generic parameter of the class (e.g. `BaseOutputParser[bool]` finds `bool` by walking the MRO for pydantic generic metadata `args`). If neither your class nor any base supplies a parameterized generic, the type cannot be inferred and accessing `OutputType` raises TypeError telling you to override the property. This usually breaks serialization/schema utilities that call `OutputType`, not `parse` itself.","triggerScenarios":"`class MyParser(BaseOutputParser): ...` without a generic parameter, then calling anything that touches `parser.OutputType` (e.g. `.get_input_schema()`, graph serialization, `.dict()`/`asdict()` in some paths).","commonSituations":"Writing a quick custom parser and forgetting the generic; refactoring a parameterized parser to remove its type argument; using tools that build JSON schemas from runnables containing the parser.","solutions":["Parameterize the base: `class MyParser(BaseOutputParser[str]):`.","Or override the property: `@property def OutputType(cls): return str`.","If you never need schema/serialization of the parser, avoid the APIs that call `OutputType` — but overriding is cheap and future-proofs."],"exampleFix":"// before\nclass MyParser(BaseOutputParser):\n    def parse(self, text: str) -> str: ...\n\n// after\nclass MyParser(BaseOutputParser[str]):\n    def parse(self, text: str) -> str: ...","handlingStrategy":"type-guard","validationCode":"import typing\n\ndef has_inferable_output_type(parser) -> bool:\n    for base in parser.__class__.mro():\n        meta = getattr(base, \"__pydantic_generic_metadata__\", None)\n        if meta and meta.get(\"args\"):\n            return True\n    return hasattr(type(parser), \"OutputType\") and not getattr(type(parser).OutputType, \"__isabstractmethod__\", False)","typeGuard":"def is_parameterized_parser(p) -> bool:\n    meta = getattr(p.__class__, \"__pydantic_generic_metadata__\", {}) or {}\n    return bool(meta.get(\"args\"))","tryCatchPattern":"try:\n    parser.OutputType\nexcept TypeError as e:\n    if \"inferable OutputType\" in str(e):\n        class FixedParser(type(parser), typing.Generic[T]): ...  # or just parameterize the original class","preventionTips":["Always parameterize custom parsers: BaseOutputParser[str]","Add an OutputType property in custom parser boilerplate","Run a schema call (get_input_schema) in parser unit tests to fail early"],"tags":["output-parsers","typing","generics","serialization"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}