JSONDecodeError when an LLM node is passing a data model (either as dict or JSON string or as plain text) as a tool argument. #859

Closed
opened 2026-02-20 17:42:09 -05:00 by yindo · 2 comments
Owner

Originally created by @deepakkrish91 on GitHub (Jul 29, 2025).

Checked other resources

  • This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/).
  • I added a clear and detailed title that summarizes the issue.
  • I read what a minimal reproducible example is (https://stackoverflow.com/help/minimal-reproducible-example).
  • I included a self-contained, minimal example that demonstrates the issue INCLUDING all the relevant imports. The code run AS IS to reproduce the issue.

Example Code

tools = [api_discovery_tool, fetch_data_model_tool, api_query_curation]

llm_with_tools = model.bind_tools(
    tools,
    parallel_tool_calls=True,
    #force_tool=True
)
def react_assistant(state: AgentState):
    # System message
    textual_description_of_tools = """
    short description of all tools defined above"""
    assistant_prompt = """you are a react agent"""
    sys_msg = SystemMessage(content=assistant_prompt.format(textual_description_of_tools=textual_description_of_tools))
    return {"messages": [llm_with_tools.invoke([sys_msg] + state["messages"])]}

# Graph
builder = StateGraph(AgentState)

# Define nodes: these do the work
builder.add_node("react_assistant", react_assistant)
builder.add_node("tools", ToolNode(tools))

# Define edges: these determine how the control flow moves
builder.add_edge(START, "react_assistant")
builder.add_conditional_edges(
    "react_assistant",
    # If the latest message (result) from react_assistant is a tool call -> tools_condition routes to tools
    # If the latest message (result) from react_assistant is a not a tool call -> tools_condition routes to END
    tools_condition,
)
builder.add_edge("tools", "react_assistant")
react_graph = builder.compile()

#testing
messages = [HumanMessage(content="What is the role title of an employee?")]

messages = sfsf_react_graph.invoke({"messages": messages})

for m in messages['messages']:
    m.pretty_print()

Error Message and Stack Trace (if applicable)

================================== Ai Message ==================================
Invalid Tool Calls:
  api_query_curation_new (call_LcakUj0OSbee64i6c39Jj9gK)
 Call ID: call_LcakUj0OSbee64i6c39Jj9gK
  Error: Function api_query_curation_new arguments:

{"user_query":"What is the role title of an employee?","query_phrase":["role title"],"data_model":{"title":"WorkProfile Details","properties":{"id":{"type":["string","null"],"title":"Assignment UUID","maxLength":32},"departmentId":{"type":["integer","null"],"format":"int64","

are not valid JSON. Received JSONDecodeError Unterminated string starting at: line 1 column 923 (char 922)

Description

The Tool Message previous to the last AI message says that it was able to fetch the right data model in dict format. But the next AI message correctly identifes a the tool call - api_curation_tool. But fails when it prepares the tool aurguments and get JSONDecode Error. I know langgarph interally serialises the tool arguments to a JSOn string, but it abruptly fails.
I tried passing the data model as plan text using

  1. a flattened custom key-value string
  2. JSON string using json.dumps method
  3. as a dict by registering the tool using from langchain.tools import tool
    in all cases I am getting the same error. - JSONDecode error.
    I checked the previous tool message. the tool retrived data model does not have any escaped characters or unwanted characters that could cause this issue. Even the context length is also max of 6000 chracters. I am using gpt-4o model.

System Info

Error while finding module specification for 'langchain_core.sys_info' (ModuleNotFoundError: No module named 'langchain_core')

Originally created by @deepakkrish91 on GitHub (Jul 29, 2025). ### Checked other resources - [x] This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/). - [x] I added a clear and detailed title that summarizes the issue. - [x] I read what a minimal reproducible example is (https://stackoverflow.com/help/minimal-reproducible-example). - [x] I included a self-contained, minimal example that demonstrates the issue INCLUDING all the relevant imports. The code run AS IS to reproduce the issue. ### Example Code ```python tools = [api_discovery_tool, fetch_data_model_tool, api_query_curation] llm_with_tools = model.bind_tools( tools, parallel_tool_calls=True, #force_tool=True ) def react_assistant(state: AgentState): # System message textual_description_of_tools = """ short description of all tools defined above""" assistant_prompt = """you are a react agent""" sys_msg = SystemMessage(content=assistant_prompt.format(textual_description_of_tools=textual_description_of_tools)) return {"messages": [llm_with_tools.invoke([sys_msg] + state["messages"])]} # Graph builder = StateGraph(AgentState) # Define nodes: these do the work builder.add_node("react_assistant", react_assistant) builder.add_node("tools", ToolNode(tools)) # Define edges: these determine how the control flow moves builder.add_edge(START, "react_assistant") builder.add_conditional_edges( "react_assistant", # If the latest message (result) from react_assistant is a tool call -> tools_condition routes to tools # If the latest message (result) from react_assistant is a not a tool call -> tools_condition routes to END tools_condition, ) builder.add_edge("tools", "react_assistant") react_graph = builder.compile() #testing messages = [HumanMessage(content="What is the role title of an employee?")] messages = sfsf_react_graph.invoke({"messages": messages}) for m in messages['messages']: m.pretty_print() ``` ### Error Message and Stack Trace (if applicable) ```shell ================================== Ai Message ================================== Invalid Tool Calls: api_query_curation_new (call_LcakUj0OSbee64i6c39Jj9gK) Call ID: call_LcakUj0OSbee64i6c39Jj9gK Error: Function api_query_curation_new arguments: {"user_query":"What is the role title of an employee?","query_phrase":["role title"],"data_model":{"title":"WorkProfile Details","properties":{"id":{"type":["string","null"],"title":"Assignment UUID","maxLength":32},"departmentId":{"type":["integer","null"],"format":"int64"," are not valid JSON. Received JSONDecodeError Unterminated string starting at: line 1 column 923 (char 922) ``` ### Description The Tool Message previous to the last AI message says that it was able to fetch the right data model in dict format. But the next AI message correctly identifes a the tool call - api_curation_tool. But fails when it prepares the tool aurguments and get JSONDecode Error. I know langgarph interally serialises the tool arguments to a JSOn string, but it abruptly fails. I tried passing the data model as plan text using 1. a flattened custom key-value string 2. JSON string using json.dumps method 3. as a dict by registering the tool using from langchain.tools import tool in all cases I am getting the same error. - JSONDecode error. I checked the previous tool message. the tool retrived data model does not have any escaped characters or unwanted characters that could cause this issue. Even the context length is also max of 6000 chracters. I am using gpt-4o model. ### System Info Error while finding module specification for 'langchain_core.sys_info' (ModuleNotFoundError: No module named 'langchain_core')
yindo added the bugpending labels 2026-02-20 17:42:09 -05:00
yindo closed this issue 2026-02-20 17:42:09 -05:00
Author
Owner

@deepakkrish91 commented on GitHub (Jul 29, 2025):

What is the best way to pass an argument which is either Dict or JSON (max of 5000 characters or 1000 tokens) to a langgraph tool during the runtime, so that we wont get into JSONDecodeError?

@deepakkrish91 commented on GitHub (Jul 29, 2025): What is the best way to pass an argument which is either Dict or JSON (max of 5000 characters or 1000 tokens) to a langgraph tool during the runtime, so that we wont get into JSONDecodeError?
Author
Owner

@casparb commented on GitHub (Sep 17, 2025):

Hi @deepakkrish91, closing this as your MRE isn't runnable, so I can’t reproduce. General advice is to not pass large JSON/data models as tool args and instead pass a small reference (e.g., data_model_id) and fetch it server-side.

If you provide a runnable MRE I'd be happy to reopen.

@casparb commented on GitHub (Sep 17, 2025): Hi @deepakkrish91, closing this as your MRE isn't runnable, so I can’t reproduce. General advice is to not pass large JSON/data models as tool args and instead pass a small reference (e.g., `data_model_id`) and fetch it server-side. If you provide a runnable MRE I'd be happy to reopen.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraph#859