From 1d993ca6830e1d5dc4bca63ee39795d56d591ce3 Mon Sep 17 00:00:00 2001 From: Emil Filipov Date: Thu, 13 Aug 2026 21:14:10 +0200 Subject: [PATCH] fix(core): don't hand the str builtin to PlainSerializer Pydantic < 2.9 calls `inspect.signature()` on an annotated serializer to decide whether to pass an `info` argument, and that raises `ValueError: no signature found for builtin type `. The failure is at class creation, so importing langchain_core.tools broke entirely on pydantic 2.7/2.8. Use a small named function instead. Verified on pydantic 2.7.4 and 2.13.4. Co-Authored-By: Claude Opus 5 (1M context) --- libs/core/langchain_core/tools/structured.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libs/core/langchain_core/tools/structured.py b/libs/core/langchain_core/tools/structured.py index 8827184565..bb01a8d7c5 100644 --- a/libs/core/langchain_core/tools/structured.py +++ b/libs/core/langchain_core/tools/structured.py @@ -37,6 +37,15 @@ if TYPE_CHECKING: from langchain_core.messages import ToolCall +def _serialize_as_str(value: Any) -> str: + """Stringify a value that has no JSON form. + + A plain function rather than the `str` builtin: Pydantic < 2.9 inspects the + serializer's signature, and `inspect.signature` raises for C builtins. + """ + return str(value) + + def _serialize_args_schema(args_schema: ArgsSchema) -> Any: """Represent a schema class as a string when dumping to JSON. @@ -56,7 +65,7 @@ def _serialize_args_schema(args_schema: ArgsSchema) -> Any: _JsonSchemaFallback = PlainSerializer( _serialize_args_schema, when_used="json-unless-none" ) -_JsonCallableFallback = PlainSerializer(str, when_used="json-unless-none") +_JsonCallableFallback = PlainSerializer(_serialize_as_str, when_used="json-unless-none") class StructuredTool(BaseTool):