langchain-ai/langchain · error · TypeError

Runnable {self.__class__.__name__} doesn't have an inferable

Error message

Runnable {self.__class__.__name__} doesn't have an inferable OutputType. Override the OutputType property to specify the output type.

What it means

`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.

Source

Thrown at libs/core/langchain_core/output_parsers/base.py:201

    def OutputType(self) -> type[T]:
        """Return the output type for the parser.

        This property is inferred from the first type argument of the class.

        Raises:
            TypeError: If the class doesn't have an inferable `OutputType`.
        """
        for base in self.__class__.mro():
            if hasattr(base, "__pydantic_generic_metadata__"):
                metadata = base.__pydantic_generic_metadata__
                if "args" in metadata and len(metadata["args"]) > 0:
                    return cast("type[T]", metadata["args"][0])

        msg = (
            f"Runnable {self.__class__.__name__} doesn't have an inferable OutputType. "
            "Override the OutputType property to specify the output type."
        )
        raise TypeError(msg)

    @override
    def invoke(
        self,
        input: str | BaseMessage,
        config: RunnableConfig | None = None,
        **kwargs: Any,
    ) -> T:
        if isinstance(input, BaseMessage):
            return self._call_with_config(
                lambda inner_input: self.parse_result(
                    [ChatGeneration(message=inner_input)]
                ),
                input,
                config,
                run_type="parser",
            )
        return self._call_with_config(

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Parameterize the base: `class MyParser(BaseOutputParser[str]):`.
  2. Or override the property: `@property def OutputType(cls): return str`.
  3. If you never need schema/serialization of the parser, avoid the APIs that call `OutputType` — but overriding is cheap and future-proofs.

Example fix

// before
class MyParser(BaseOutputParser):
    def parse(self, text: str) -> str: ...

// after
class MyParser(BaseOutputParser[str]):
    def parse(self, text: str) -> str: ...
Defensive patterns

Strategy: type-guard

Validate before calling

import typing

def has_inferable_output_type(parser) -> bool:
    for base in parser.__class__.mro():
        meta = getattr(base, "__pydantic_generic_metadata__", None)
        if meta and meta.get("args"):
            return True
    return hasattr(type(parser), "OutputType") and not getattr(type(parser).OutputType, "__isabstractmethod__", False)

Type guard

def is_parameterized_parser(p) -> bool:
    meta = getattr(p.__class__, "__pydantic_generic_metadata__", {}) or {}
    return bool(meta.get("args"))

Try / catch

try:
    parser.OutputType
except TypeError as e:
    if "inferable OutputType" in str(e):
        class FixedParser(type(parser), typing.Generic[T]): ...  # or just parameterize the original class

Prevention

When it happens

Trigger: `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).

Common situations: 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.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/0fabdcec5b6530d6. Report an issue: GitHub.