{"record":{"id":"8ca1b50f608a015d","repo":"alibaba/arthas","slug":"tool-with-name-toolname-not-found","errorCode":null,"errorMessage":"Tool with name '${toolName}' not found","messagePattern":"Tool with name '(.+?)' not found","errorType":"exception","errorClass":"McpError","httpStatus":null,"severity":"warning","filePath":"arthas-mcp-server/src/main/java/com/taobao/arthas/mcp/server/protocol/server/McpNettyServer.java","lineNumber":303,"sourceCode":"\t\t});\n\t}\n\n\tpublic CompletableFuture<Void> removeTool(String toolName) {\n\t\tif (toolName == null) {\n\t\t\tCompletableFuture<Void> future = new CompletableFuture<>();\n\t\t\tfuture.completeExceptionally(new McpError(\"Tool name must not be null\"));\n\t\t\treturn future;\n\t\t}\n\t\tif (this.serverCapabilities.getTools() == null) {\n\t\t\tCompletableFuture<Void> future = new CompletableFuture<>();\n\t\t\tfuture.completeExceptionally(new McpError(\"Server must be configured with tool capabilities\"));\n\t\t\treturn future;\n\t\t}\n\n\t\treturn CompletableFuture.supplyAsync(() -> {\n\t\t\tboolean removed = this.tools.removeIf(spec -> spec.getTool().getName().equals(toolName));\n\t\t\tif (!removed) {\n\t\t\t\tthrow new CompletionException(new McpError(\"Tool with name '\" + toolName + \"' not found\"));\n\t\t\t}\n\t\t\tthis.toolsByName.remove(toolName);\n\t\t\tlogger.debug(\"Removed tool handler: {}\", toolName);\n\t\t\treturn null;\n\t\t}).thenCompose(ignored -> {\n\t\t\tif (this.serverCapabilities.getTools().getListChanged()) {\n\t\t\t\treturn notifyToolsListChanged();\n\t\t\t}\n\t\t\treturn CompletableFuture.completedFuture(null);\n\t\t}).exceptionally(ex -> {\n\t\t\tThrowable cause = (ex instanceof CompletionException) ? ex.getCause() : ex;\n\t\t\tlogger.error(\"Error while removing tool '{}'\", toolName, cause);\n\t\t\tthrow new CompletionException(cause);\n\t\t});\n\t}\n\n\tpublic CompletableFuture<Void> notifyToolsListChanged() {\n\t\tlogger.debug(\"Notifying clients about tool list changes\");","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/arthas-mcp-server/src/main/java/com/taobao/arthas/mcp/server/protocol/server/McpNettyServer.java#L285-L321","documentation":"McpNettyServer.removeTool throws McpError (wrapped in CompletionException) when no registered tool matches the given name. The list is filtered by Tool.name equality; if nothing matched, removeIf returns false and the server treats it as an error rather than a no-op.","triggerScenarios":"Thrown at arthas-mcp-server/src/main/java/com/taobao/arthas/mcp/server/protocol/server/McpNettyServer.java:303 when the library encounters an invalid state.","commonSituations":"Stale UI/client calling remove for a tool that was never added or already removed; a race where the tool was removed concurrently; a typo in the tool name.","solutions":["Check the current tool list before calling removeTool.","Treat not-found as acceptable by catching McpError and ignoring it.","Verify the exact (case-sensitive) tool name before removing."],"exampleFix":"// before\nserver.removeTool(\"arthas.dump\").join(); // not found\n\n// after\nboolean exists = server.getTools().stream()\n    .anyMatch(t -> t.getTool().getName().equals(\"arthas.dump\"));\nif (exists) server.removeTool(\"arthas.dump\").join();","handlingStrategy":"try-catch","validationCode":"boolean exists = server.getTools().stream()\n    .anyMatch(t -> t.getTool().getName().equals(name));\nif (exists) server.removeTool(name).join(); // else no-op","typeGuard":null,"tryCatchPattern":"try { server.removeTool(name).join(); }\ncatch (CompletionException e) {\n  if (e.getCause() instanceof io.modelcontextprotocol.spec.McpError && e.getCause().getMessage().contains(\"not found\")) { /* ignore */ }\n  else throw e;\n}","preventionTips":["Check existence before removeTool.","Treat not-found as idempotent success.","Verify exact case-sensitive tool name."],"tags":["mcp","arthas-mcp-server","registration","not-found"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}