Skip to content

tool_call_id not passed to on_tool_start callback in BaseTool.run() #34168

@gustavhartz

Description

@gustavhartz

Checked other resources

  • 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-cli
  • 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-perplexity
  • langchain-prompty
  • langchain-qdrant
  • langchain-xai
  • Other / not sure / general

Example Code (Python)

from uuid import UUID
  from typing import Any
  from langchain_core.callbacks import BaseCallbackHandler
  from langchain_core.tools import tool
  from langchain_core.messages import ToolCall

  class DebugCallback(BaseCallbackHandler):
      def on_tool_start(
          self,
          serialized: dict[str, Any],
          input_str: str,
          *,
          run_id: UUID,
          parent_run_id: UUID | None = None,
          tags: list[str] | None = None,
          metadata: dict[str, Any] | None = None,
          inputs: dict[str, Any] | None = None,
          **kwargs: Any,
      ) -> None:
          print(f"on_tool_start kwargs: {kwargs}")
          print(f"on_tool_start metadata: {metadata}")
          # tool_call_id is NOT available in kwargs or metadata

  @tool
  def get_weather(location: str) -> str:
      """Get weather for a location"""
      return f"Sunny in {location}"

  # Invoke with a ToolCall (which contains tool_call_id)
  tool_call = ToolCall(name="get_weather", args={"location": "Paris"}, id="call_123")
  result = get_weather.invoke(
      tool_call,
      config={"callbacks": [DebugCallback()]}
  )
  print(f"Result: {result}")

Error Message and Stack Trace (if applicable)

Output:
  on_tool_start kwargs: {}
  on_tool_start metadata: None
  Result: Sunny in Paris

Description

Description:

When invoking a tool with a ToolCall input (which contains an id field for tool_call_id), the tool_call_id is correctly extracted in _prep_run_args() and passed to
BaseTool.run(). However, BaseTool.run() does not forward the tool_call_id to the callback handlers in on_tool_start.

In langchain_core/tools/base.py, the run() method extracts tool_call_id as a named parameter:

  def run(
      self,
      tool_input: str | dict[str, Any],
      ...
      tool_call_id: str | None = None,  # Extracted here
      **kwargs: Any,  # tool_call_id is NOT in kwargs
  ):
      ...
      run_manager = callback_manager.on_tool_start(
          {"name": self.name, "description": self.description},
          tool_input_str,
          ...
          **kwargs,  # tool_call_id NOT passed!
      )

Expected behavior: The tool_call_id should be passed to on_tool_start (and on_tool_end) callbacks, either via kwargs or as a dedicated parameter.

Suggested fix: Add tool_call_id=tool_call_id to the callback_manager.on_tool_start() call in BaseTool.run().

System Info

System Info:

OS: Darwin
OS Version: Darwin Kernel Version 25.1.0
Python Version: 3.13.7
langchain_core: 1.0.7
langchain: 1.0.8

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugRelated to a bug, vulnerability, unexpected error with an existing featurecoreRelated to the package `langchain-core`

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions