alibaba/spring-ai-alibaba · error · BizException
TOOL_NOT_FOUND
TOOL_NOT_FOUND
Error message
TOOL_NOT_FOUND
What it means
TOOL_NOT_FOUND is thrown by PluginServiceImpl.publishTool when no ToolEntity exists for the given toolId within the caller's workspace. The library throws it because publishing a tool that cannot be resolved in the current workspace is an invalid request; the lookup is scoped by workspaceId, so a tool that exists in another workspace still yields null.
Source
Thrown at spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/base/service/impl/PluginServiceImpl.java:579
toolMapper.updateById(entity);
// update cache
String key = getToolCacheKey(context.getWorkspaceId(), toolId);
redisManager.put(key, entity);
}
/**
* Publishes a tool after testing
* @param toolId Tool ID
*/
@Override
public void publishTool(String toolId) {
RequestContext context = RequestContextHolder.getRequestContext();
ToolEntity entity = getToolById(context.getWorkspaceId(), toolId);
if (entity == null) {
throw new BizException(ErrorCode.TOOL_NOT_FOUND.toError());
}
if (entity.getTestStatus() != ToolTestStatus.PASSED) {
throw new BizException(ErrorCode.TOOL_NOT_TESTED.toError());
}
entity.setStatus(ToolStatus.PUBLISHED);
entity.setEnabled(true);
toolMapper.updateById(entity);
// update cache
String key = getToolCacheKey(context.getWorkspaceId(), toolId);
redisManager.put(key, entity);
}
/**
* Retrieves a plugin entity from cache or database
* @param workspaceId Workspace IDView on GitHub (pinned to f82da0b50f)
Solutions
- Verify the toolId exists in the current workspace (query the tool list API for the workspace before publishing).
- Re-fetch the tool via getToolById/workspace tool list to get a fresh valid ID after deletion or recreation.
- Check that RequestContext has the correct workspaceId set — switch to the workspace owning the tool.
- If the ID comes from an external reference, validate it before calling publish.
Example fix
// before
pluginService.publishTool(request.getParameter("toolId")); // may be deleted/stale
// after
ToolEntity tool = pluginService.getToolById(workspaceId, toolId);
if (tool == null) {
throw new BizException(ErrorCode.TOOL_NOT_FOUND.toError());
}
pluginService.publishTool(toolId); Defensive patterns
Strategy: validation
Validate before calling
ToolEntity tool = pluginService.getToolById(workspaceId, toolId);
if (tool == null) { throw new BizException(ErrorCode.TOOL_NOT_FOUND.toError()); } Type guard
boolean toolExistsInWorkspace(String workspaceId, String toolId) {
return pluginService.getToolById(workspaceId, toolId) != null;
} Try / catch
try {
pluginService.publishTool(toolId);
} catch (BizException e) {
if (ErrorCode.TOOL_NOT_FOUND.name().equals(e.getCode())) {
// refresh tool list / correct workspace
}
throw e;
} Prevention
- Always resolve the toolId from a workspace-scoped list call in the same workspace as the request context.
- Refetch IDs before publishing instead of caching them across sessions.
- Log workspaceId with toolId in errors to quickly spot cross-workspace mistakes.
- Validate ID existence client-side before calling publish.
When it happens
Trigger: Calling publishTool(toolId) with a toolId that does not exist, was deleted, belongs to a different workspace than RequestContext.getWorkspaceId(), or with a malformed/typo'd ID.
Common situations: Stale toolId cached in a client after the tool was deleted; calling the publish endpoint from a workspace-scoped UI where the selected workspace differs from the tool's owning workspace; copying an ID from another environment (dev vs prod database).
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/0482ce934b8bd424.
Report an issue: GitHub.