langchain-ai/langchain · error · TypeError

Runnable {self.get_name()} doesn't have an inferable InputTy

Error message

Runnable {self.get_name()} doesn't have an inferable InputType. Override the InputType property to specify the input type.

What it means

Raised by the `InputType` property on `Runnable` when LangChain cannot infer the input type of a custom Runnable: no pydantic-model base contributes it and no `__orig_bases__` entry is a parameterized `Runnable[Input, Output]` generic (checked via `get_args` needing exactly `_RUNNABLE_GENERIC_NUM_ARGS` type args). Type inference is needed to build `input_schema` for validation, streaming, and graph rendering, so a `TypeError` with the Runnable's name is raised, advising you to override the property.

Source

Thrown at libs/core/langchain_core/runnables/base.py:341

                if (
                    "args" in metadata
                    and len(metadata["args"]) == _RUNNABLE_GENERIC_NUM_ARGS
                ):
                    return cast("type[Input]", metadata["args"][0])

        # If we didn't find a Pydantic model in the parent classes,
        # then loop through __orig_bases__. This corresponds to
        # Runnables that are not pydantic models.
        for cls in self.__class__.__orig_bases__:  # type: ignore[attr-defined]
            type_args = get_args(cls)
            if type_args and len(type_args) == _RUNNABLE_GENERIC_NUM_ARGS:
                return cast("type[Input]", type_args[0])

        msg = (
            f"Runnable {self.get_name()} doesn't have an inferable InputType. "
            "Override the InputType property to specify the input type."
        )
        raise TypeError(msg)

    @property
    def OutputType(self) -> type[Output]:  # noqa: N802
        """Output Type.

        The type of output this `Runnable` produces specified as a type annotation.

        Raises:
            TypeError: If the output type cannot be inferred.
        """
        # First loop through bases -- this will help generic
        # any pydantic models.
        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"]) == _RUNNABLE_GENERIC_NUM_ARGS

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Parameterize the base class: `class MyRunnable(Runnable[InputType, OutputType])`
  2. Or override the property explicitly: `@property def InputType(self): return str`
  3. If the class is a pydantic model, annotate input-bearing fields so the base-class scan finds the type

Example fix

# before
class Shout(Runnable):
    def invoke(self, text, config=None):
        return text.upper()
Shout().get_input_schema()  # TypeError: no inferable InputType

# after
class Shout(Runnable[str, str]):
    def invoke(self, text, config=None):
        return text.upper()
Defensive patterns

Strategy: type-guard

Validate before calling

import inspect
from typing import get_args, get_origin
from langchain_core.runnables import Runnable

def has_inferable_input_type(runnable: Runnable) -> bool:
    try:
        _ = runnable.InputType
        return True
    except TypeError:
        return False

Type guard

def is_parameterized_runnable(cls: type) -> bool:
    import typing
    return any(
        get_origin(b) is Runnable or (get_origin(b) is not None and len(get_args(b)) == 2)
        for b in getattr(cls, "__orig_bases__", [])
    )

Try / catch

try:
    schema = runnable.get_input_schema()
except TypeError as e:
    if "inferable InputType" in str(e):
        runnable.InputType = property(lambda self: str)  # or fix the class definition
    else:
        raise

Prevention

When it happens

Trigger: Defining `class MyRunnable(Runnable):` (bare, unparameterized base) or `class MyRunnable(RunnableABC)` where no base is `Runnable[SomeInput, SomeOutput]`, then accessing `.InputType` / `.get_input_schema()` / using it in a chain that inspects schemas. Works for `class MyRunnable(Runnable[str, str])`.

Common situations: Writing custom LCEL components without generic parameters; converting older `Chain`-style classes to `Runnable`; introspection by LangGraph/LangSmith UI that calls `get_input_schema` on every node.

Related errors


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