{"record":{"id":"0482ce934b8bd424","repo":"alibaba/spring-ai-alibaba","slug":"tool-not-found","errorCode":"TOOL_NOT_FOUND","errorMessage":"TOOL_NOT_FOUND","messagePattern":"TOOL_NOT_FOUND","errorType":"error_code","errorClass":"BizException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/base/service/impl/PluginServiceImpl.java","lineNumber":579,"sourceCode":"\n\t\ttoolMapper.updateById(entity);\n\n\t\t// update cache\n\t\tString key = getToolCacheKey(context.getWorkspaceId(), toolId);\n\t\tredisManager.put(key, entity);\n\t}\n\n\t/**\n\t * Publishes a tool after testing\n\t * @param toolId Tool ID\n\t */\n\t@Override\n\tpublic void publishTool(String toolId) {\n\t\tRequestContext context = RequestContextHolder.getRequestContext();\n\n\t\tToolEntity entity = getToolById(context.getWorkspaceId(), toolId);\n\t\tif (entity == null) {\n\t\t\tthrow new BizException(ErrorCode.TOOL_NOT_FOUND.toError());\n\t\t}\n\n\t\tif (entity.getTestStatus() != ToolTestStatus.PASSED) {\n\t\t\tthrow new BizException(ErrorCode.TOOL_NOT_TESTED.toError());\n\t\t}\n\n\t\tentity.setStatus(ToolStatus.PUBLISHED);\n\t\tentity.setEnabled(true);\n\t\ttoolMapper.updateById(entity);\n\n\t\t// update cache\n\t\tString key = getToolCacheKey(context.getWorkspaceId(), toolId);\n\t\tredisManager.put(key, entity);\n\t}\n\n\t/**\n\t * Retrieves a plugin entity from cache or database\n\t * @param workspaceId Workspace ID","sourceCodeStart":561,"sourceCodeEnd":597,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/base/service/impl/PluginServiceImpl.java#L561-L597","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"// before\npluginService.publishTool(request.getParameter(\"toolId\")); // may be deleted/stale\n// after\nToolEntity tool = pluginService.getToolById(workspaceId, toolId);\nif (tool == null) {\n    throw new BizException(ErrorCode.TOOL_NOT_FOUND.toError());\n}\npluginService.publishTool(toolId);","handlingStrategy":"validation","validationCode":"ToolEntity tool = pluginService.getToolById(workspaceId, toolId);\nif (tool == null) { throw new BizException(ErrorCode.TOOL_NOT_FOUND.toError()); }","typeGuard":"boolean toolExistsInWorkspace(String workspaceId, String toolId) {\n    return pluginService.getToolById(workspaceId, toolId) != null;\n}","tryCatchPattern":"try {\n    pluginService.publishTool(toolId);\n} catch (BizException e) {\n    if (ErrorCode.TOOL_NOT_FOUND.name().equals(e.getCode())) {\n        // refresh tool list / correct workspace\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["plugin","tool","not-found","workspace"],"backgroundTag":"resource-not-found","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}