{"record":{"id":"8e1f9aee925326a8","repo":"langchain-ai/langchain","slug":"runnable-self-get-name-doesn-t-have-an-inferab","errorCode":null,"errorMessage":"Runnable {self.get_name()} doesn't have an inferable InputType. Override the InputType property to specify the input type.","messagePattern":"Runnable (.+?) doesn't have an inferable InputType\\. Override the InputType property to specify the input type\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/runnables/base.py","lineNumber":341,"sourceCode":"                if (\n                    \"args\" in metadata\n                    and len(metadata[\"args\"]) == _RUNNABLE_GENERIC_NUM_ARGS\n                ):\n                    return cast(\"type[Input]\", metadata[\"args\"][0])\n\n        # If we didn't find a Pydantic model in the parent classes,\n        # then loop through __orig_bases__. This corresponds to\n        # Runnables that are not pydantic models.\n        for cls in self.__class__.__orig_bases__:  # type: ignore[attr-defined]\n            type_args = get_args(cls)\n            if type_args and len(type_args) == _RUNNABLE_GENERIC_NUM_ARGS:\n                return cast(\"type[Input]\", type_args[0])\n\n        msg = (\n            f\"Runnable {self.get_name()} doesn't have an inferable InputType. \"\n            \"Override the InputType property to specify the input type.\"\n        )\n        raise TypeError(msg)\n\n    @property\n    def OutputType(self) -> type[Output]:  # noqa: N802\n        \"\"\"Output Type.\n\n        The type of output this `Runnable` produces specified as a type annotation.\n\n        Raises:\n            TypeError: If the output type cannot be inferred.\n        \"\"\"\n        # First loop through bases -- this will help generic\n        # any pydantic models.\n        for base in self.__class__.mro():\n            if hasattr(base, \"__pydantic_generic_metadata__\"):\n                metadata = base.__pydantic_generic_metadata__\n                if (\n                    \"args\" in metadata\n                    and len(metadata[\"args\"]) == _RUNNABLE_GENERIC_NUM_ARGS","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/runnables/base.py#L323-L359","documentation":"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.","triggerScenarios":"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])`.","commonSituations":"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.","solutions":["Parameterize the base class: `class MyRunnable(Runnable[InputType, OutputType])`","Or override the property explicitly: `@property def InputType(self): return str`","If the class is a pydantic model, annotate input-bearing fields so the base-class scan finds the type"],"exampleFix":"# before\nclass Shout(Runnable):\n    def invoke(self, text, config=None):\n        return text.upper()\nShout().get_input_schema()  # TypeError: no inferable InputType\n\n# after\nclass Shout(Runnable[str, str]):\n    def invoke(self, text, config=None):\n        return text.upper()","handlingStrategy":"type-guard","validationCode":"import inspect\nfrom typing import get_args, get_origin\nfrom langchain_core.runnables import Runnable\n\ndef has_inferable_input_type(runnable: Runnable) -> bool:\n    try:\n        _ = runnable.InputType\n        return True\n    except TypeError:\n        return False","typeGuard":"def is_parameterized_runnable(cls: type) -> bool:\n    import typing\n    return any(\n        get_origin(b) is Runnable or (get_origin(b) is not None and len(get_args(b)) == 2)\n        for b in getattr(cls, \"__orig_bases__\", [])\n    )","tryCatchPattern":"try:\n    schema = runnable.get_input_schema()\nexcept TypeError as e:\n    if \"inferable InputType\" in str(e):\n        runnable.InputType = property(lambda self: str)  # or fix the class definition\n    else:\n        raise","preventionTips":["Always declare custom Runnables as Runnable[Input, Output]","Add a smoke test that calls get_input_schema() on each custom component","Review generics were not stripped when copying example code"],"tags":["runnables","lcel","type-inference","typeerror","custom-components"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}