spring-ai icon indicating copy to clipboard operation
spring-ai copied to clipboard

Cannot invoke "String.equals(Object)" because "toolName" is null

Open longshaoqing opened this issue 9 months ago • 2 comments

Bug description Sending OK to call Tool Calling error: ERROR 29356 --- [ient-2-Worker-0] o.s.ai.chat.model.MessageAggregator : Aggregation Error

java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "toolName" is null

Environment spring-ai-bom:1.0.0-M6 spring-ai-openai-spring-boot-starter JDK21

Steps to reproduce @Component public class UserTools { @Tool(name = "getOK",description = "OK") public String getOK() { return "ok!ok!ok!"; } }

@Autowired private UserTools userTools; @Bean public ChatClient chatClient(OpenAiChatModel model, ChatMemory chatMemory) { return ChatClient .builder(model) .defaultSystem(""" 你是小清,一个温柔可爱机智的智能助手。 """) .defaultTools(userTools) // Tool Calling .build(); }

@Operation(summary = "对话") @PostMapping(value = "/conversation",produces = "text/html;charset=utf-8") public Flux<String> chatClient(@RequestBody ChatDto chatDto) { return chatClient.prompt() .user(chatDto.getPrompt()) .stream() .content(); }

longshaoqing avatar Apr 19 '25 18:04 longshaoqing

使用1.0.0-M7试试

yangtuooc avatar Apr 20 '25 02:04 yangtuooc

It seems that tool.name() can be null, which causes an IllegalArgumentException in the prefixedToolName(...) method.

@Override
public ToolDefinition getToolDefinition() {
	return ToolDefinition.builder()
		.name(McpToolUtils.prefixedToolName(this.asyncMcpClient.getClientInfo().name(), this.tool.name()))
		.description(this.tool.description())
		.inputSchema(ModelOptionsUtils.toJsonString(this.tool.inputSchema()))
		.build();
	}

I looked into this issue and it seems that the exception occurs when tool.name() is null, which causes McpToolUtils.prefixedToolName(...) to throw an IllegalArgumentException.

To prevent this, I think it would be helpful to add a simple null/empty check before calling prefixedToolName(...). For example:

if (StringUtils.isEmpty(toolName)) {
    // If the tool name is not provided, use a fallback name (e.g., the class name)
    toolName = this.tool.getClass().getSimpleName();
    log.warn("Tool name is null. Using fallback name: {}", toolName);
}

lllilllilllilili avatar Apr 20 '25 02:04 lllilllilllilili

stare

dyrnq avatar May 31 '25 07:05 dyrnq

me too

xuliang0825 avatar Jul 14 '25 09:07 xuliang0825

解决了吗,我也遇到了类似问题

Cynric92 avatar Nov 07 '25 05:11 Cynric92