spring-projects/spring-ai · warning
Tool name '${toolName}' may not be compatible with some LLMs
Error message
Tool name '${toolName}' may not be compatible with some LLMs (e.g., OpenAI). Consider using only alphanumeric characters, underscores, hyphens, and dots. What it means
ToolUtils.validateToolName logs a warning when a tool name does not match the recommended pattern (alphanumeric, underscore, hyphen, dot). Some LLM providers such as OpenAI enforce strict name characters, and names outside this set may be rejected or mangled by the model. The name is still used; only a warning is emitted after a basic hasText assertion.
Source
Thrown at spring-ai-model/src/main/java/org/springframework/ai/tool/support/ToolUtils.java:131
.filter(entry -> entry.getValue() > 1)
.map(Map.Entry::getKey)
.toList();
}
public static List<String> getDuplicateToolNames(ToolCallback... toolCallbacks) {
Assert.notNull(toolCallbacks, "toolCallbacks cannot be null");
return getDuplicateToolNames(Arrays.asList(toolCallbacks));
}
/**
* Validates that a tool name follows recommended naming conventions. Logs a warning
* if the tool name contains characters that may not be compatible with some LLMs.
* @param toolName the tool name to validate
*/
private static void validateToolName(String toolName) {
Assert.hasText(toolName, "Tool name cannot be null or empty");
if (logger.isWarnEnabled() && !RECOMMENDED_NAME_PATTERN.matcher(toolName).matches()) {
logger.warn("Tool name '" + toolName + "' may not be compatible with some LLMs (e.g., OpenAI). "
+ "Consider using only alphanumeric characters, underscores, hyphens, and dots.");
}
}
}
View on GitHub (pinned to 98a7beda4f)
Solutions
- Rename the tool to use only [a-zA-Z0-9_.-], e.g. convert camelCase or spaced names to snake_case.
- Set an explicit tool name instead of deriving it from class/method names (e.g. @Tool(name = "get_weather")).
- If names come from a registry, sanitize them before registration (replace invalid chars with '_').
Example fix
// before
@Tool(name = "Weather Lookup (live)")
String weather(String city) { ... }
// after
@Tool(name = "weather_lookup_live")
String weather(String city) { ... } Defensive patterns
Strategy: validation
Validate before calling
private static final Pattern OK = Pattern.compile("[a-zA-Z0-9_.-]+");
if (!OK.matcher(toolName).matches()) throw new IllegalArgumentException("Invalid tool name: " + toolName); Type guard
boolean isValidToolName(String n) { return n != null && n.matches("[a-zA-Z0-9_.-]+"); } Prevention
- Always set explicit names via @Tool(name=...) using [a-zA-Z0-9_.-] only.
- Sanitize auto-generated names (replace invalid chars with '_').
- Avoid deriving names from localized text or human-readable labels.
- Add a startup assertion that every registered tool name matches the recommended pattern.
When it happens
Trigger: Any tool definition whose name is passed through getToolName -> validateToolName contains characters like spaces, '@', '(', ')', non-ASCII letters, or is empty (empty throws IllegalArgumentException from Assert.hasText).
Common situations: Auto-generating tool names from method signatures or FQCNs (dots are fine but spaces/parens are not); exposing Spring bean method names with special chars; localizing tool names.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Tool name '<toolName>' already exists. Using unique tool nam
- SSE connection '<connectionName>' requires a 'url' property.
- Method must not be null
- Method must have exactly 1 parameter (List<McpSchema.Prompt>
- Method must have exactly 1 parameter (List<McpSchema.Resourc
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/6e8b80c4066a93fd.
Report an issue: GitHub.