alibaba/spring-ai-alibaba · error · BizException
TOOL_NOT_TESTED
TOOL_NOT_TESTED
Error message
TOOL_NOT_TESTED
What it means
TOOL_NOT_TESTED is thrown by PluginServiceImpl.publishTool when the tool exists but its ToolTestStatus is not PASSED. The library enforces that only tools whose latest test run passed may be published, to prevent broken tool definitions from going live.
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:583
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 ID
* @param pluginId Plugin ID
* @return Plugin entity or null if not found
*/
private PluginEntity getPluginById(String workspaceId, String pluginId) {View on GitHub (pinned to f82da0b50f)
Solutions
- Run the tool test for this toolId and ensure it passes before publishing.
- Check entity.getTestStatus() via the tool detail API; only publish when it is ToolTestStatus.PASSED.
- If the tool was edited after testing, re-run the test to refresh the status.
- If status is stale due to a bug in test bookkeeping, re-save/re-test the tool to update the persisted state.
Example fix
// before
pluginService.publishTool(toolId); // throws if testStatus != PASSED
// after
ToolEntity tool = pluginService.getToolById(workspaceId, toolId);
if (tool == null || tool.getTestStatus() != ToolTestStatus.PASSED) {
pluginService.testTool(toolId); // run test first
}
pluginService.publishTool(toolId); Defensive patterns
Strategy: validation
Validate before calling
ToolEntity tool = pluginService.getToolById(workspaceId, toolId);
if (tool == null || tool.getTestStatus() != ToolTestStatus.PASSED) {
throw new IllegalStateException("tool must pass tests before publishing");
} Type guard
boolean isPublishable(ToolEntity tool) {
return tool != null && tool.getTestStatus() == ToolTestStatus.PASSED;
} Try / catch
try {
pluginService.publishTool(toolId);
} catch (BizException e) {
if (ErrorCode.TOOL_NOT_TESTED.name().equals(e.getCode())) {
// trigger a test run, then retry publish once status is PASSED
}
throw e;
} Prevention
- Make 'run test' a required workflow step before the publish action is enabled.
- Re-run tests automatically after every tool definition edit.
- Surface testStatus in the UI next to the publish action.
- Gate publish behind a status check in client code.
When it happens
Trigger: Calling publishTool(toolId) on a tool that has never been tested, whose testStatus is FAILED or PENDING, or that was modified after its last successful test so its recorded status is stale.
Common situations: Developer publishes immediately after creating/editing a tool without running the test step in the studio UI; a test run failed silently upstream; tool definition edited after passing tests, resetting test status.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/9e48e37966b2008c.
Report an issue: GitHub.