Typescript example of build a real-world agent in quickstart document doesn't work, it happens "tool_call_id" error

After following the quickstart document to build a real word agent, it aways throws this error:
400 An assistant message with ‘tool_calls’ must be followed by tool messages responding to each ‘tool_call_id’

I think this might be related to that pending bug fix fix(openai): pair reasoning with function_call id; add tests by pawel-twardziak · Pull Request #9082 · langchain-ai/langchainjs · GitHub

I will check it.

Hmmm the example works for me:

{
  messages: [
    HumanMessage {
      "id": "29710469-f7bd-4e30-a0e8-998c35b8173d",
      "content": "What's the weather in Tokyo?",
      "additional_kwargs": {},
      "response_metadata": {}
    },
    AIMessage {
      "id": "msg_01YAxpwQzBjL6MZqqpjHPsQH",
      "content": [
        {
          "type": "tool_use",
          "id": "toolu_015E8qECr7A8AkFGHAqUYnnX",
          "name": "get_weather",
          "input": {
            "city": "Tokyo"
          }
        }
      ],
      "name": "model",
      "additional_kwargs": {
        "model": "claude-sonnet-4-5-20250929",
        "id": "msg_01YAxpwQzBjL6MZqqpjHPsQH",
        "type": "message",
        "role": "assistant",
        "stop_reason": "tool_use",
        "stop_sequence": null,
        "usage": {
          "input_tokens": 606,
          "cache_creation_input_tokens": 0,
          "cache_read_input_tokens": 0,
          "cache_creation": {
            "ephemeral_5m_input_tokens": 0,
            "ephemeral_1h_input_tokens": 0
          },
          "output_tokens": 53,
          "service_tier": "standard"
        }
      },
      "response_metadata": {
        "model": "claude-sonnet-4-5-20250929",
        "id": "msg_01YAxpwQzBjL6MZqqpjHPsQH",
        "stop_reason": "tool_use",
        "stop_sequence": null,
        "usage": {
          "input_tokens": 606,
          "cache_creation_input_tokens": 0,
          "cache_read_input_tokens": 0,
          "cache_creation": {
            "ephemeral_5m_input_tokens": 0,
            "ephemeral_1h_input_tokens": 0
          },
          "output_tokens": 53,
          "service_tier": "standard"
        },
        "type": "message",
        "role": "assistant",
        "model_provider": "anthropic"
      },
      "tool_calls": [
        {
          "name": "get_weather",
          "args": {
            "city": "Tokyo"
          },
          "id": "toolu_015E8qECr7A8AkFGHAqUYnnX",
          "type": "tool_call"
        }
      ],
      "invalid_tool_calls": [],
      "usage_metadata": {
        "input_tokens": 606,
        "output_tokens": 53,
        "total_tokens": 659,
        "input_token_details": {
          "cache_creation": 0,
          "cache_read": 0
        }
      }
    },
    ToolMessage {
      "id": "1ee82833-84f4-4f5e-8482-36e27f09b114",
      "content": "It's always sunny in Tokyo!",
      "name": "get_weather",
      "additional_kwargs": {},
      "response_metadata": {},
      "tool_call_id": "toolu_015E8qECr7A8AkFGHAqUYnnX"
    },
    AIMessage {
      "id": "msg_01JHisN4bK4L6j129EQ7WCtW",
      "content": "The weather in Tokyo is sunny! ☀️",
      "name": "model",
      "additional_kwargs": {
        "model": "claude-sonnet-4-5-20250929",
        "id": "msg_01JHisN4bK4L6j129EQ7WCtW",
        "type": "message",
        "role": "assistant",
        "stop_reason": "end_turn",
        "stop_sequence": null,
        "usage": {
          "input_tokens": 678,
          "cache_creation_input_tokens": 0,
          "cache_read_input_tokens": 0,
          "cache_creation": {
            "ephemeral_5m_input_tokens": 0,
            "ephemeral_1h_input_tokens": 0
          },
          "output_tokens": 14,
          "service_tier": "standard"
        }
      },
      "response_metadata": {
        "model": "claude-sonnet-4-5-20250929",
        "id": "msg_01JHisN4bK4L6j129EQ7WCtW",
        "stop_reason": "end_turn",
        "stop_sequence": null,
        "usage": {
          "input_tokens": 678,
          "cache_creation_input_tokens": 0,
          "cache_read_input_tokens": 0,
          "cache_creation": {
            "ephemeral_5m_input_tokens": 0,
            "ephemeral_1h_input_tokens": 0
          },
          "output_tokens": 14,
          "service_tier": "standard"
        },
        "type": "message",
        "role": "assistant",
        "model_provider": "anthropic"
      },
      "tool_calls": [],
      "invalid_tool_calls": [],
      "usage_metadata": {
        "input_tokens": 678,
        "output_tokens": 14,
        "total_tokens": 692,
        "input_token_details": {
          "cache_creation": 0,
          "cache_read": 0
        }
      }
    }
  ]
}

@DeepenLau have you changed the provider for OpenAI? Or any changes to the code?

For openai:gpt-5 it also works for me:

{
  messages: [
    HumanMessage {
      "id": "9f0c1e16-87d1-429e-8a32-041974071a99",
      "content": "What's the weather in Tokyo?",
      "additional_kwargs": {},
      "response_metadata": {}
    },
    AIMessage {
      "id": "chatcmpl-CT6x0kWc3KJnZHt9Ph1VbOR5ZcCKE",
      "content": "",
      "name": "model",
      "additional_kwargs": {
        "tool_calls": [
          {
            "id": "call_rqQIxuJLO81Jaf69mfwni2V2",
            "type": "function",
            "function": "[Object]"
          }
        ]
      },
      "response_metadata": {
        "tokenUsage": {
          "promptTokens": 141,
          "completionTokens": 151,
          "totalTokens": 292
        },
        "finish_reason": "tool_calls",
        "model_provider": "openai",
        "model_name": "gpt-5-2025-08-07"
      },
      "tool_calls": [
        {
          "name": "get_weather",
          "args": {
            "city": "Tokyo"
          },
          "type": "tool_call",
          "id": "call_rqQIxuJLO81Jaf69mfwni2V2"
        }
      ],
      "invalid_tool_calls": [],
      "usage_metadata": {
        "output_tokens": 151,
        "input_tokens": 141,
        "total_tokens": 292,
        "input_token_details": {
          "audio": 0,
          "cache_read": 0
        },
        "output_token_details": {
          "audio": 0,
          "reasoning": 128
        }
      }
    },
    ToolMessage {
      "id": "040c7f44-3629-444b-93d2-203265386898",
      "content": "It's always sunny in Tokyo!",
      "name": "get_weather",
      "additional_kwargs": {},
      "response_metadata": {},
      "tool_call_id": "call_rqQIxuJLO81Jaf69mfwni2V2"
    },
    AIMessage {
      "id": "chatcmpl-CT6x6kv44j5BlB3KNc7EjsoSmFxaj",
      "content": "It’s always sunny in Tokyo!",
      "name": "model",
      "additional_kwargs": {},
      "response_metadata": {
        "tokenUsage": {
          "promptTokens": 176,
          "completionTokens": 592,
          "totalTokens": 768
        },
        "finish_reason": "stop",
        "model_provider": "openai",
        "model_name": "gpt-5-2025-08-07"
      },
      "tool_calls": [],
      "invalid_tool_calls": [],
      "usage_metadata": {
        "output_tokens": 592,
        "input_tokens": 176,
        "total_tokens": 768,
        "input_token_details": {
          "audio": 0,
          "cache_read": 0
        },
        "output_token_details": {
          "audio": 0,
          "reasoning": 576
        }
      }
    }
  ]
}

I changed the provider for to deepseek, and this error is throw when call the second times of agent.invoke(). The first time is work

1 Like

How are you invoking it second time? Have you modified the code? What’s the invocations flow?

I followed the “Build a real-word agent“ step in this page and change the model provider to deepseek.

And then then execute the last agent.invoke() to get “thinkYouResponse“, it throw this error

I have the same issue with custom graph - running ok for the first time but get this error at the 2nd time.

1 Like

Had the same error here, same scenario whenever I made a second time call into an already existant graph I would get this error.

downgrading from 1.1.3 to 1.0.0 got it working again, hope it helps

1.1.1 and 1.1.2 both presented the same issue.

@reinvent-heucles Thanks. I’m getting this error with 1.1.0 of langchain-core and langchain. Maybe I downgrade this further to try out…

I could try to fix it, but… it is not happening to me with the latest versions (1.1.x) at all :person_gesturing_ok:

this code:

import { createAgent, tool } from "langchain";
import * as z from "zod";
import dotenv from 'dotenv'
import { MemorySaver } from "@langchain/langgraph";
import { initChatModel } from "langchain";

dotenv.config()

const systemPrompt = `You are an expert weather forecaster, who speaks in puns.

You have access to two tools:

- get_weather_for_location: use this to get the weather for a specific location
- get_user_location: use this to get the user's location

If a user asks you for the weather, make sure you know the location. If you can tell from the question that they mean wherever they are, use the get_user_location tool to find their location.`;

const checkpointer = new MemorySaver();

const responseFormat = z.object({
  punny_response: z.string(),
  weather_conditions: z.string().optional(),
});

const model = await initChatModel(
  "deepseek-chat",
  { temperature: 0.5, timeout: 1800, maxTokens: 3200, modelProvider: 'deepseek', maxRetires: 2 }
);

const getWeather = tool(
  (input) => `It's always sunny in ${input.city}!`,
  {
    name: "get_weather_for_location",
    description: "Get the weather for a given city",
    schema: z.object({
      city: z.string().describe("The city to get the weather for"),
    }),
  }
);

// type AgentRuntime = ToolRuntime<unknown, { user_id: string }>;

const getUserLocation = tool(
  (_, config) => {
    const { user_id } = config.context;
    return user_id === "1" ? "Florida" : "SF";
  },
  {
    name: "get_user_location",
    description: "Retrieve user information based on user ID",
  }
);

const agent = createAgent({
  model,
  systemPrompt: systemPrompt,
  tools: [getUserLocation, getWeather],
  responseFormat,
  checkpointer,
});

// `thread_id` is a unique identifier for a given conversation.
const config = {
  configurable: { thread_id: "1" },
  context: { user_id: "1" },
};

const response = await agent.invoke(
  { messages: [{ role: "user", content: "what is the weather outside?" }] },
  config
);
console.log(response.structuredResponse);
// {
//   punny_response: "Florida is still having a 'sun-derful' day ...",
//   weather_conditions: "It's always sunny in Florida!"
// }

// Note that we can continue the conversation using the same `thread_id`.
const thankYouResponse = await agent.invoke(
  { messages: [{ role: "user", content: "thank you!" }] },
  config
);
console.log(thankYouResponse.structuredResponse);
// {
//   punny_response: "You're 'thund-erfully' welcome! ...",
//   weather_conditions: undefined
// }

has successfully produced 5 answers in a row like this:

{
  punny_response: `Well, it looks like Florida is living up to its sunny reputation! I'd say the weather is absolutely "sun-sational" - you could say it's a real "bright" spot on the map! Don't forget your sunscreen, or you might get "burned" by that Florida sunshine!`,                                                                                                                                                                                          
  weather_conditions: 'Sunny'
}
{
  punny_response: `You're very welcome! I'm always "weather" to help - it's my "fore-cast" in life! If you need any more weather "pun-dits", just give me a "cloud" shout!`
}

Have you tried to remove all the dependencies phisically and install them from scratch?