Skip to content

Tool silently exposes no arguments when args_schema is incomplete #39099

Description

Submission checklist

  • This is a bug, not a usage question.
  • I added a clear and descriptive title that summarizes this issue.
  • I used the GitHub search to find a similar question and didn't find it.
  • I am sure that this is a bug in LangChain rather than my code.
  • The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
  • This is not related to the langchain-community package.
  • I posted a self-contained, minimal, reproducible example. A maintainer can copy it and run it AS IS.

Package (Required)

  • langchain
  • langchain-openai
  • langchain-anthropic
  • langchain-classic
  • langchain-core
  • langchain-model-profiles
  • langchain-tests
  • langchain-text-splitters
  • langchain-chroma
  • langchain-deepseek
  • langchain-exa
  • langchain-fireworks
  • langchain-groq
  • langchain-huggingface
  • langchain-mistralai
  • langchain-nomic
  • langchain-ollama
  • langchain-openrouter
  • langchain-perplexity
  • langchain-qdrant
  • langchain-xai
  • Other / not sure / general

Related Issues / PRs

Closest I found, neither a duplicate: #31035 (fields with an alias silently dropped from the
schema — same family, different cause) and #33300 (InjectedState treated as required, but at the
LangGraph CLI layer).

Reproduction Steps / Example Code (Python)

from langchain_core.tools import tool
from langchain_core.utils.function_calling import convert_to_openai_tool
from pydantic import BaseModel
from typing_extensions import Annotated


class Container(BaseModel):
    rows: list["Row"] = []          # "Row" is declared below, after the tool is decorated


@tool
def my_tool(real_arg: Annotated[str, "a real argument"], container: Container):
    """A tool whose schema depends on a forward reference that is not resolvable yet."""
    return "ok"


class Row(BaseModel):
    name: str


print(my_tool.get_input_schema().__pydantic_complete__)
print(list(my_tool.args))
print(convert_to_openai_tool(my_tool)["function"]["parameters"])

# Output:
#   False
#   []
#   {'properties': {}, 'type': 'object'}
#
# The tool is handed to the model with NO parameters at all, and nothing is logged or raised.
# Moving `class Row` above `Container` fixes it -- but nothing points you there.
#
# A plain @dataclass behaves the same. Reproduced on langchain-core 0.3.29, 0.3.75, 1.0.0,
# 1.2.6, 1.2.22, 1.2.27 and 1.5.1, and on Python 3.10 / 3.11 / 3.12 / 3.13 (pydantic 2.12.5).
# Both langchain-google-genai and langchain-aws send the same empty declaration.

Error Message and Stack Trace (if applicable)

# Nothing is raised at schema-build time -- that is the problem. It surfaces later,
# because the advertised schema and the validated schema disagree:
#
#   my_tool.invoke({"name": "my_tool", "args": {}, "id": "1", "type": "tool_call"})

pydantic_core._pydantic_core.ValidationError: 2 validation errors for my_tool
real_arg
  Field required [type=missing, input_value={}, input_type=dict]
container
  Field required [type=missing, input_value={}, input_type=dict]

Description

To be clear about scope: the unresolved forward reference is a mistake in user code. The bug is that langchain-core degrades silently instead of surfacing it — the tool is still handed to the model, just with zero parameters.

What makes this hard to find is that the same mistake is already a hard error one level up. If the unresolved name sits directly in the tool signature:

@tool
def my_tool(real_arg: Annotated[str, "a real argument"], rows: list["Row"]):
    ...
File "langchain_core/tools/base.py", line 329, in create_schema_from_function
NameError: name 'Row' is not defined

Nested one level deeper, the same unresolvable name produces an empty schema and silence. That inconsistency is the core of this report.

Mechanically: the incomplete model degrades inspect.signature() to (**data: Any), get_all_basemodel_annotations() therefore returns {}, and tool_call_schema reads that as "this tool has no arguments" rather than "the schema could not be resolved".

This is easy to hit with LangGraph, where InjectedState parameters are typically typed with a rich application object whose entire type graph must be resolvable at decoration time. In our case 12 of 13 tools in one module were affected for months without anyone noticing: an empty schema fails differently depending on the model — one provider invented field names, another sent {} — so the symptom looks like a flaky model rather than a broken schema.

Suggested fix

Fail loudly, matching the direct-signature case. Any of:

  • Warn or raise in BaseTool.tool_call_schema when the subset model ends up empty while args_schema.model_fields is not — those two disagreeing is always a bug.
  • Warn when args_schema.__pydantic_complete__ is False.
  • Call args_schema.model_rebuild() once before introspection. This is enough to fix the example above:
my_tool.args_schema.model_rebuild(force=True)
# -> convert_to_openai_tool now returns ['real_arg', 'container']

Happy to open a PR for whichever direction you prefer.

System Info

System Information

OS: Linux
OS Version: #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026
Python Version: 3.12.11 (main, Jun 29 2025, 16:24:38) [Clang 20.1.4 ]

Package Information

langchain_core: 1.2.27
langsmith: 0.10.10
langchain_google_genai: 4.2.1
langgraph_sdk: 0.3.15

Optional packages not installed

deepagents
deepagents-cli

Other Dependencies

anyio: 4.14.2
distro: 1.9.0
filetype: 1.2.0
google-genai: 1.75.0
httpx: 0.28.1
jsonpatch: 1.33
orjson: 3.11.9
packaging: 24.2
pydantic: 2.12.5
pyyaml: 6.0.3
requests: 2.34.2
requests-toolbelt: 1.0.0
sniffio: 1.3.1
tenacity: 9.1.4
typing-extensions: 4.16.0
uuid-utils: 0.17.0
websockets: 16.1.1
xxhash: 3.8.1
zstandard: 0.25.0

Also reproduced on langchain-core 0.3.29, 0.3.75, 1.0.0, 1.2.6, 1.2.22 and 1.5.1,
and on Python 3.10.18, 3.11.13 and 3.13.5.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugRelated to a bug, vulnerability, unexpected error with an existing featurecore`langchain-core` package issues & PRsexternal

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions