{"record":{"id":"2254751114d339d1","repo":"microsoft/autogen","slug":"failed-to-create-a-valid-pydantic-v2-model-for-na","errorCode":null,"errorMessage":"Failed to create a valid Pydantic v2 model for {name}","messagePattern":"Failed to create a valid Pydantic v2 model for (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-ext/src/autogen_ext/tools/langchain/_langchain_adapter.py","lineNumber":179,"sourceCode":"            )\n\n        # Determine args_type\n        if self._langchain_tool.args_schema:  # pyright: ignore\n            args_type = self._langchain_tool.args_schema  # pyright: ignore\n        else:\n            # Infer args_type from the callable's signature\n            sig = inspect.signature(cast(Callable[..., Any], self._callable))  # type: ignore\n            fields = {\n                k: (v.annotation, Field(...))\n                for k, v in sig.parameters.items()\n                if k != \"self\" and v.kind not in (inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD)\n            }\n            args_type = create_model(f\"{name}Args\", **fields)  # type: ignore\n            # Note: type ignore is used due to a LangChain typing limitation\n\n        # Ensure args_type is a subclass of BaseModel\n        if not issubclass(args_type, BaseModel):\n            raise ValueError(f\"Failed to create a valid Pydantic v2 model for {name}\")\n\n        # Assume return_type as Any if not specified\n        return_type: Type[Any] = object\n\n        super().__init__(args_type, return_type, name, description)\n\n    async def run(self, args: BaseModel, cancellation_token: CancellationToken) -> Any:\n        # Prepare arguments\n        kwargs = args.model_dump()\n\n        # Determine if the callable is asynchronous\n        if inspect.iscoroutinefunction(self._callable):\n            return await self._callable(**kwargs)\n        else:\n            # Run in a thread to avoid blocking the event loop\n            return await asyncio.to_thread(self._call_sync, kwargs)\n\n    def _call_sync(self, kwargs: Dict[str, Any]) -> Any:","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/tools/langchain/_langchain_adapter.py#L161-L197","documentation":"After resolving args_schema (either the tool's own or one synthesized via create_model), LangChainToolAdapter requires it to be a Pydantic v2 BaseModel subclass. Pydantic v1 model classes or non-model classes (dataclasses, TypedDict) fail issubclass() and raise ValueError. The adapter's run() relies on v2 model_dump(), so v1 schemas cannot work.","triggerScenarios":"Wrapping a LangChain tool whose args_schema is a pydantic.v1.BaseModel (common with langchain<0.1 era tools or langchain_community tools still on v1), a dataclass, or a TypedDict. The issubclass(args_type, BaseModel) check fails and the error names the tool.","commonSituations":"Mixing old langchain-community tools (pydantic v1 schemas) with modern autogen-ext; having pydantic v1 installed alongside v2 via langchain's compat shim; a tool that sets args_schema to a plain class for documentation purposes.","solutions":["Rebuild the tool's args_schema as a Pydantic v2 model (from pydantic import BaseModel) and recreate the tool with @tool or StructuredTool.from_function.","Re-register the legacy function through a fresh @tool decorator so a v2 schema is auto-generated from the signature.","Upgrade langchain/langchain-core to a release that uses pydantic v2 schemas natively.","Ensure only pydantic v2 is imported in your tool definition module (watch for 'from pydantic.v1 import BaseModel' imports)."],"exampleFix":"# before\nfrom pydantic.v1 import BaseModel as V1BaseModel\n\nclass FetchArgs(V1BaseModel):\n    q: str\n\nfetch = StructuredTool(name=\"fetch\", func=do_fetch, args_schema=FetchArgs)\n\n# after\nfrom pydantic import BaseModel, Field\n\nclass FetchArgs(BaseModel):\n    q: str = Field(description=\"query\")\n\nfetch = StructuredTool.from_function(func=do_fetch, args_schema=FetchArgs)","handlingStrategy":"type-guard","validationCode":"from pydantic import BaseModel\n\nschema = getattr(tool, \"args_schema\", None)\nif schema is not None and not (isinstance(schema, type) and issubclass(schema, BaseModel)):\n    raise TypeError(\"args_schema must be a pydantic v2 BaseModel; rebuild the tool with @tool\")","typeGuard":"from pydantic import BaseModel\nfrom typing import Any, TypeGuard\n\ndef is_pydantic_v2_schema(schema: Any) -> TypeGuard[type[BaseModel]]:\n    return isinstance(schema, type) and issubclass(schema, BaseModel)","tryCatchPattern":"try:\n    adapter = LangChainToolAdapter(tool)\nexcept ValueError as e:\n    if \"valid Pydantic v2 model\" in str(e):\n        raise TypeError(\"Rebuild the tool with a pydantic v2 args_schema\") from e\n    raise","preventionTips":["Ban `from pydantic.v1 import` imports via lint rule in projects using autogen-ext.","Regenerate legacy tools through @tool so v2 schemas are synthesized automatically.","Run `python -c \"import pydantic; print(pydantic.VERSION)\"` when integrating old langchain tools."],"tags":["langchain","pydantic","pydantic-v2","interop"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}