custom tool type number error #4562

Closed
opened 2026-02-21 18:07:02 -05:00 by yindo · 1 comment
Owner

Originally created by @guogeer on GitHub (Jul 11, 2024).

Self Checks

  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report (我已阅读并同意 Language Policy).
  • 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)
  • Please do not modify this template :) and fill in all the required fields.

Dify version

0.6.13

Cloud or Self Hosted

Self Hosted (Source)

Steps to reproduce

when custom tool input field include the type of number, call tool in chat flow cause error:
Failed to invoke tool: argument of type 'int' is not iterable
20240711-185805
screenshot-20240711-185619

✔️ Expected Behavior

output json data

Actual Behavior

Failed to invoke tool: argument of type 'int' is not iterable

Originally created by @guogeer on GitHub (Jul 11, 2024). ### Self Checks - [X] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general). - [X] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones. - [X] I confirm that I am using English to submit this report (我已阅读并同意 [Language Policy](https://github.com/langgenius/dify/issues/1542)). - [X] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:) - [X] Please do not modify this template :) and fill in all the required fields. ### Dify version 0.6.13 ### Cloud or Self Hosted Self Hosted (Source) ### Steps to reproduce when custom tool input field include the type of number, call tool in chat flow cause error: Failed to invoke tool: argument of type 'int' is not iterable ![20240711-185805](https://github.com/langgenius/dify/assets/5010851/6afe76b0-2a0e-40a9-a949-f7f5f7b67c2b) ![screenshot-20240711-185619](https://github.com/langgenius/dify/assets/5010851/38e753eb-4b1e-4ce6-9459-82cc1eac02a8) ### ✔️ Expected Behavior output json data ### ❌ Actual Behavior Failed to invoke tool: argument of type 'int' is not iterable
yindo added the 🐞 bug label 2026-02-21 18:07:02 -05:00
yindo closed this issue 2026-02-21 18:07:02 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jul 11, 2024):

Hey @guogeer! 👋 I'm here to help you with any bugs, questions, or contributions while you wait for the human maintainer.

The error "argument of type 'int' is not iterable" occurs because an integer is being treated as an iterable. To fix this, ensure that the tool parameters are correctly handled and that no iteration is attempted on an integer. Here is a potential fix for the agent_invoke method in the ToolEngine class:

  1. Ensure tool_parameters is always a dictionary before processing.
  2. Add a check to handle cases where the parameters might include non-iterable types.

Here is the modified code:

class ToolEngine:
    @staticmethod
    def agent_invoke(
        tool: Tool, tool_parameters: Union[str, dict],
        user_id: str, tenant_id: str, message: Message, invoke_from: InvokeFrom,
        agent_tool_callback: DifyAgentCallbackHandler,
        trace_manager: Optional[TraceQueueManager] = None
    ) -> tuple[str, list[tuple[MessageFile, bool]], ToolInvokeMeta]:
        """
        Agent invokes the tool with the given arguments.
        """
        # Ensure tool_parameters is a dictionary
        if isinstance(tool_parameters, str):
            parameters = [
                parameter for parameter in tool.get_runtime_parameters() 
                if parameter.form == ToolParameter.ToolParameterForm.LLM
            ]
            if parameters and len(parameters) == 1:
                tool_parameters = {
                    parameters[0].name: tool_parameters
                }
            else:
                raise ValueError(f"tool_parameters should be a dict, but got a string: {tool_parameters}")
        elif not isinstance(tool_parameters, dict):
            raise ValueError(f"tool_parameters should be a dict, but got: {type(tool_parameters)}")

        # Check for non-iterable types in tool_parameters
        for key, value in tool_parameters.items():
            if isinstance(value, (int, float)):
                tool_parameters[key] = str(value)

        # invoke the tool
        try:
            agent_tool_callback.on_tool_start(
                tool_name=tool.identity.name, 
                tool_inputs=tool_parameters
            )

            meta, response = ToolEngine._invoke(tool, tool_parameters, user_id)
            response = ToolFileMessageTransformer.transform_tool_invoke_messages(
                messages=response, 
                user_id=user_id, 
                tenant_id=tenant_id, 
                conversation_id=message.conversation_id
            )
            binary_files = ToolEngine._extract_tool_response_binary(response)
            message_files = ToolEngine._create_message_files(
                tool_messages=binary_files,
                agent_message=message,
                invoke_from=invoke_from,
                user_id=user_id
            )

            plain_text = ToolEngine._convert_tool_response_to_str(response)

            agent_tool_callback.on_tool_end(
                tool_name=tool.identity.name,
                tool_inputs=tool_parameters,
                tool_outputs=plain_text,
                message_id=message.id,
                trace_manager=trace_manager
            )

            return meta, response
        except Exception as e:
            raise ToolEngineInvokeError(f"Failed to invoke tool: {str(e)}")

This code ensures that tool_parameters is always a dictionary and converts any non-iterable types (like integers and floats) to strings before processing, preventing the error [1].

To continue talking to Dosu, mention @dosu.

@dosubot[bot] commented on GitHub (Jul 11, 2024): <!-- Greeting --> Hey @guogeer! 👋 I'm here to help you with any bugs, questions, or contributions while you wait for the human maintainer. <!-- Answer --> The error "argument of type 'int' is not iterable" occurs because an integer is being treated as an iterable. To fix this, ensure that the tool parameters are correctly handled and that no iteration is attempted on an integer. Here is a potential fix for the `agent_invoke` method in the `ToolEngine` class: 1. Ensure `tool_parameters` is always a dictionary before processing. 2. Add a check to handle cases where the parameters might include non-iterable types. Here is the modified code: ```python class ToolEngine: @staticmethod def agent_invoke( tool: Tool, tool_parameters: Union[str, dict], user_id: str, tenant_id: str, message: Message, invoke_from: InvokeFrom, agent_tool_callback: DifyAgentCallbackHandler, trace_manager: Optional[TraceQueueManager] = None ) -> tuple[str, list[tuple[MessageFile, bool]], ToolInvokeMeta]: """ Agent invokes the tool with the given arguments. """ # Ensure tool_parameters is a dictionary if isinstance(tool_parameters, str): parameters = [ parameter for parameter in tool.get_runtime_parameters() if parameter.form == ToolParameter.ToolParameterForm.LLM ] if parameters and len(parameters) == 1: tool_parameters = { parameters[0].name: tool_parameters } else: raise ValueError(f"tool_parameters should be a dict, but got a string: {tool_parameters}") elif not isinstance(tool_parameters, dict): raise ValueError(f"tool_parameters should be a dict, but got: {type(tool_parameters)}") # Check for non-iterable types in tool_parameters for key, value in tool_parameters.items(): if isinstance(value, (int, float)): tool_parameters[key] = str(value) # invoke the tool try: agent_tool_callback.on_tool_start( tool_name=tool.identity.name, tool_inputs=tool_parameters ) meta, response = ToolEngine._invoke(tool, tool_parameters, user_id) response = ToolFileMessageTransformer.transform_tool_invoke_messages( messages=response, user_id=user_id, tenant_id=tenant_id, conversation_id=message.conversation_id ) binary_files = ToolEngine._extract_tool_response_binary(response) message_files = ToolEngine._create_message_files( tool_messages=binary_files, agent_message=message, invoke_from=invoke_from, user_id=user_id ) plain_text = ToolEngine._convert_tool_response_to_str(response) agent_tool_callback.on_tool_end( tool_name=tool.identity.name, tool_inputs=tool_parameters, tool_outputs=plain_text, message_id=message.id, trace_manager=trace_manager ) return meta, response except Exception as e: raise ToolEngineInvokeError(f"Failed to invoke tool: {str(e)}") ``` This code ensures that `tool_parameters` is always a dictionary and converts any non-iterable types (like integers and floats) to strings before processing, preventing the error <sup>[[1]](https://github.com/langgenius/dify/blob/main/api/core/tools/tool_engine.py)</sup>. <!-- Dosu Comment Footer --> *To continue talking to [Dosu](https://dosu.dev), mention @dosu.*
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#4562