{"record":{"id":"9e7330f85f3b8a24","repo":"alibaba/spring-ai-alibaba","slug":"updatepluginerror","errorCode":"UpdatePluginError","errorMessage":"Failed to create plugin.","messagePattern":"Failed to create plugin\\.","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":165,"sourceCode":"\t\t\tentity.setDescription(plugin.getDescription());\n\n\t\t\tString config = JsonUtils.toJson(plugin.getConfig());\n\t\t\tentity.setConfig(config);\n\n\t\t\tentity.setSource(plugin.getSource());\n\t\t\tentity.setGmtModified(new Date());\n\t\t\tentity.setModifier(context.getWorkspaceId());\n\n\t\t\tthis.updateById(entity);\n\n\t\t\tString key = getPluginCacheKey(entity.getWorkspaceId(), entity.getPluginId());\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_PLUGIN_ERROR.toError(), e);\n\t\t}\n\t}\n\n\t/**\n\t * Deletes a plugin and its associated tools\n\t * @param pluginId ID of the plugin to delete\n\t */\n\t@Override\n\tpublic void deletePlugin(String pluginId) {\n\t\tRequestContext context = RequestContextHolder.getRequestContext();\n\t\tPluginEntity entity = getPluginById(context.getWorkspaceId(), pluginId);\n\t\tif (entity == null) {\n\t\t\treturn;\n\t\t}\n\n\t\t// delete all tools first\n\t\tLambdaQueryWrapper<ToolEntity> queryWrapper = new LambdaQueryWrapper<>();\n\t\tqueryWrapper.eq(ToolEntity::getPluginId, pluginId)","sourceCodeStart":147,"sourceCodeEnd":183,"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#L147-L183","documentation":"Generic wrapper thrown by PluginServiceImpl.updatePlugin when a non-BizException occurs while persisting or caching the plugin update (name conflicts and not-found cases are thrown as their own codes first).","triggerScenarios":"updatePlugin fails during entity mutation, JsonUtils.toJson of config, DB update, or redisManager.put of the cache entry.","commonSituations":"Redis outage on cache refresh; oversized/invalid plugin config breaking JSON serialization; DB constraint violations or connection loss during update.","solutions":["Inspect the wrapped cause for the real error","Verify Redis and database health","Validate plugin config JSON-serializability before calling update","Catch BizException(UpdatePluginError) and return a server-error response"],"exampleFix":"// before\npluginService.updatePlugin(plugin);\n// after\ntry {\n    JsonUtils.toJson(plugin.getConfig()); // fail fast on bad config\n    pluginService.updatePlugin(plugin);\n} catch (BizException e) {\n    log.error(\"update failed: {}\", e.getCause());\n    throw e;\n}","handlingStrategy":"try-catch","validationCode":"// ensure config is JSON-serializable and entity exists before update\nJsonUtils.toJson(plugin.getConfig());\npluginService.getPlugin(plugin.getPluginId());","typeGuard":null,"tryCatchPattern":"try {\n    pluginService.updatePlugin(plugin);\n} catch (BizException e) {\n    log.error(\"Update failed, cause: {}\", e.getCause());\n    throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());\n}","preventionTips":["Pre-validate config payloads for size/serializability","Monitor Redis on the update path","Keep plugin config JSON schema versioned","Log wrapped causes, not just the BizException message"],"tags":["plugin","persistence","redis","serialization"],"backgroundTag":"database-write-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"}