{"record":{"id":"bb3dc03ede11e9e1","repo":"alibaba/spring-ai-alibaba","slug":"updatetoolerror","errorCode":"UpdateToolError","errorMessage":"Failed to create tool.","messagePattern":"Failed to create tool\\.","errorType":"error_code","errorClass":"BizException","httpStatus":500,"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":395,"sourceCode":"\t\t\tentity.setApiSchema(yaml);\n\t\t\tentity.setGmtModified(new Date());\n\t\t\tentity.setModifier(context.getAccountId());\n\n\t\t\tif (entity.getStatus() == ToolStatus.PUBLISHED) {\n\t\t\t\tentity.setStatus(ToolStatus.PUBLISHED_EDITING);\n\t\t\t}\n\n\t\t\ttoolMapper.updateById(entity);\n\n\t\t\t// cache it\n\t\t\tString key = getToolCacheKey(entity.getWorkspaceId(), entity.getToolId());\n\t\t\tredisManager.put(key, entity);\n\t\t}\n\t\tcatch (BizException e) {\n\t\t\tthrow e;\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new BizException(ErrorCode.UPDATE_TOOL_ERROR.toError(), e);\n\t\t}\n\t}\n\n\t/**\n\t * Deletes a tool\n\t * @param toolId ID of the tool to delete\n\t */\n\t@Override\n\tpublic void deleteTool(String toolId) {\n\t\tRequestContext context = RequestContextHolder.getRequestContext();\n\t\t// delete from db\n\t\tToolEntity entity = getToolById(context.getWorkspaceId(), toolId);\n\t\tif (entity == null) {\n\t\t\treturn;\n\t\t}\n\n\t\tentity.setStatus(ToolStatus.DELETED);\n\t\tentity.setGmtModified(new Date());","sourceCodeStart":377,"sourceCodeEnd":413,"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#L377-L413","documentation":"Generic wrapper thrown by updateTool (message text reused from the create path) when any non-BizException escapes the update flow. The original failure is attached as cause — typically the database update (toolMapper.updateById) or the Redis cache put (redisManager.put) failed.","triggerScenarios":"Any non-BizException inside updateTool after validation passes: DB update failure (row locked, connection lost, schema mismatch), JsonUtils.toJson failure on the new config, redisManager.put failure writing the refreshed cache entry.","commonSituations":"Database connection pool exhausted under load; optimistic-lock/column-length issues on apiSchema or config columns; Redis node down making cache writes fail.","solutions":["Read the chained cause of this BizException in server logs to find the real exception.","Verify database connectivity and that the tool row still exists and is updatable.","Check Redis availability for the tool cache write.","Retry the update once the infrastructure issue is resolved.","If config JSON exceeds column limits, shorten the apiSchema/config payloads."],"exampleFix":"// before: no cause inspection\ncatch (BizException e) { log.error(\"update failed\"); }\n\n// after: surface the cause\ncatch (BizException e) {\n    log.error(\"update failed\", e.getCause());\n}","handlingStrategy":"try-catch","validationCode":"// confirm the tool still exists before attempting the update\nTool current = toolService.getTool(toolId);\nif (current == null) { throw new IllegalStateException(\"tool missing, abort update\"); }","typeGuard":null,"tryCatchPattern":"try {\n    toolService.updateTool(context, tool);\n} catch (BizException e) {\n    // wrapped infrastructure failure: inspect and rethrow with cause\n    Throwable cause = e.getCause();\n    log.error(\"updateTool infra failure\", cause);\n    throw new RuntimeException(cause);\n}","preventionTips":["Always inspect e.getCause() to distinguish DB vs cache vs serialization failures.","Add idempotent retry only for transient infra causes (connection reset, timeout).","Monitor DB pool saturation and Redis availability for the admin service.","Keep entity JSON columns adequately sized for apiSchema/config payloads."],"tags":["persistence","database","plugin-tools"],"backgroundTag":"api-request-failed","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"}