{"record":{"id":"11cba6efd69e2c4f","repo":"alibaba/spring-ai-alibaba","slug":"createtoolerror","errorCode":"CreateToolError","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":326,"sourceCode":"\n\t\t\tentity.setGmtCreate(new Date());\n\t\t\tentity.setGmtModified(new Date());\n\t\t\tentity.setCreator(context.getAccountId());\n\t\t\tentity.setModifier(context.getAccountId());\n\n\t\t\ttoolMapper.insert(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\n\t\t\treturn toolId;\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.CREATE_TOOL_ERROR.toError(), e);\n\t\t}\n\t}\n\n\t/**\n\t * Updates an existing tool\n\t * @param tool Updated tool information\n\t */\n\t@Override\n\tpublic void updateTool(Tool tool) {\n\t\ttry {\n\t\t\tRequestContext context = RequestContextHolder.getRequestContext();\n\n\t\t\tString toolName = tool.getName();\n\t\t\tString pluginId = tool.getPluginId();\n\n\t\t\tToolEntity entity = getToolById(context.getWorkspaceId(), tool.getToolId());\n\t\t\tif (entity == null) {\n\t\t\t\tthrow new BizException(ErrorCode.TOOL_NOT_FOUND.toError());","sourceCodeStart":308,"sourceCodeEnd":344,"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#L308-L344","documentation":"Generic wrapper thrown by createTool when any unexpected exception escapes the tool creation flow (and is not already a BizException). The original exception is attached as the cause, so the real failure (DB insert error, cache write failure, JSON serialization, etc.) must be read from the cause.","triggerScenarios":"Any non-BizException thrown inside createTool: toolMapper insert failure (constraint violation, DB down), Redis cache put failure, JsonUtils.toJson failure on the tool config, BeanCopierUtils.copy problems, or IdGenerator failures.","commonSituations":"Database unavailable or schema mismatch after version upgrade; oversized tool config JSON exceeding a column length; Redis connection issues; duplicate primary key generation collisions.","solutions":["Inspect the chained cause of this BizException in logs to identify the real underlying exception.","Verify database connectivity and that the tool table schema matches the current entity (ToolEntity) columns.","Ensure the tool config is JSON-serializable and not excessively large.","Check Redis connectivity used by redisManager for tool caching.","Retry createTool after fixing the infra issue; fix the payload if it is a data problem."],"exampleFix":"// before: oversized config silently breaks insert\nconfig.setLargeSchema(hugeYamlString); // > column size\ntoolService.createTool(context, tool);\n\n// after: validate size first\nif (hugeYamlString.length() > MAX_SCHEMA_LENGTH) {\n    throw new IllegalArgumentException(\"api schema too large\");\n}\ntoolService.createTool(context, tool);","handlingStrategy":"try-catch","validationCode":"// sanity-check payload before the call\nif (tool.getName() == null || tool.getConfig() == null) {\n    throw new IllegalArgumentException(\"tool name and config are required\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    toolService.createTool(context, tool);\n} catch (BizException e) {\n    // CREATE_TOOL_ERROR wraps the real cause\n    log.error(\"createTool failed\", e.getCause());\n    throw new IllegalStateException(\"tool creation failed\", e.getCause());\n}","preventionTips":["Always log/surface e.getCause() — the message is generic but the cause is specific.","Keep tool config JSON within column size limits.","Monitor DB and Redis health for the admin service.","Apply schema migrations before deploying code that writes new entity fields."],"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"}