alibaba/spring-ai-alibaba · warning
Tool selection failed, using all tools: {}
Error message
Tool selection failed, using all tools: {} What it means
ToolSelectionInterceptor asks an LLM to pick a subset of available tools; selectTools wraps that selection in a broad catch, and on any failure it logs this warning and falls back to passing ALL tools to the model. The workflow continues, but the model sees the full tool set, which can degrade selection quality and increase token usage.
Source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/toolselection/ToolSelectionInterceptor.java:176
String responseText = response.getResult().getOutput().getText();
// Parse JSON response
Set<String> selected = parseToolSelection(responseText);
// Add always-include tools
selected.addAll(alwaysInclude);
// Limit to maxTools if specified
if (maxTools != null && selected.size() > maxTools) {
List<String> selectedList = new ArrayList<>(selected);
selected = new HashSet<>(selectedList.subList(0, maxTools));
}
return selected;
}
catch (Exception e) {
log.warn("Tool selection failed, using all tools: {}", e.getMessage());
return new HashSet<>(toolNames);
}
}
private Set<String> parseToolSelection(String responseText) {
try {
// Try to parse as JSON
ToolSelectionResponse response = objectMapper.readValue(responseText, ToolSelectionResponse.class);
return new HashSet<>(response.tools);
}
catch (Exception e) {
// Fallback: extract tool names from text
log.debug("Failed to parse JSON, using fallback extraction");
return new HashSet<>();
}
}
@OverrideView on GitHub (pinned to f82da0b50f)
Solutions
- Inspect the selection model's raw response (logged context) and strengthen the selection prompt with explicit output-format instructions and an example.
- Make parseToolSelection more tolerant: strip markdown fences, trim whitespace, and ignore unknown tool names instead of failing.
- Use a more capable model for tool selection.
- If the fallback is acceptable, silence the noise by fixing the common parse failure case; if not, tighten validation of the selection response.
Example fix
// before (brittle parser)
Set<String> names = new HashSet<>(List.of(responseText.split(",")));
// after
String json = responseText.replaceAll("^```(json)?|```$", "").trim();
Set<String> names = parseNames(json, toolNames); // ignore unknown names Defensive patterns
Strategy: fallback
Validate before calling
static boolean isParsableSelection(String responseText) {
if (responseText == null) return false;
String s = responseText.replaceAll("```(json)?", "").trim();
return s.startsWith("[") || s.startsWith("{") || !s.isEmpty();
} Try / catch
try {
selected = selectionModel.call(selectionPrompt);
} catch (Exception e) {
log.warn("Tool selection failed, using all tools: {}", e.getMessage());
return new HashSet<>(toolNames);
} Prevention
- Give the selection model a strict output format with an example
- Strip markdown fences before parsing
- Ignore unknown tool names instead of failing the parse
- Use a reliable model for the selection step
When it happens
Trigger: selectTools throws inside the selection flow — typically when parseToolSelection cannot parse the model's responseText into a valid tool-name set (malformed JSON, hallucinated tool names, empty response), or the selection model call itself errors.
Common situations: 1) The selection LLM returns prose or fenced markdown instead of the expected JSON/name list. 2) The selection model names tools that don't exist in toolNames. 3) A small/weak selection model (e.g. a cheap endpoint) that frequently produces unparseable output. 4) Selection prompt template misconfigured so instructions don't match the parser.
Related errors
- Primary model failed: {}
- Fallback model {} failed: {}
- Path traversal not allowed:
- Path must start with one of :
- maxTools must be > 0
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/9d8b96d759107eea.
Report an issue: GitHub.