{"record":{"id":"15910fcf447feb54","repo":"alibaba/arthas","slug":"resource-with-uri-resourceuri-already-exists","errorCode":null,"errorMessage":"Resource with URI '${resourceUri}' already exists","messagePattern":"Resource with URI '(.+?)' already exists","errorType":"exception","errorClass":"McpError","httpStatus":null,"severity":"error","filePath":"arthas-mcp-server/src/main/java/com/taobao/arthas/mcp/server/protocol/server/McpNettyServer.java","lineNumber":435,"sourceCode":"\t// Resource Management\n\t// ---------------------------------------\n\n\tpublic CompletableFuture<Void> addResource(McpServerFeatures.ResourceSpecification resourceSpecification) {\n\t\tif (resourceSpecification == null || resourceSpecification.getResource() == null) {\n\t\t\tCompletableFuture<Void> future = new CompletableFuture<>();\n\t\t\tfuture.completeExceptionally(new McpError(\"Resource must not be null\"));\n\t\t\treturn future;\n\t\t}\n\t\tif (this.serverCapabilities.getResources() == null) {\n\t\t\tCompletableFuture<Void> future = new CompletableFuture<>();\n\t\t\tfuture.completeExceptionally(new McpError(\"Server must be configured with resource capabilities\"));\n\t\t\treturn future;\n\t\t}\n\n\t\treturn CompletableFuture.supplyAsync(() -> {\n\t\t\tif (this.resources.putIfAbsent(resourceSpecification.getResource().getUri(),\n\t\t\t\t\tresourceSpecification) != null) {\n\t\t\t\tthrow new CompletionException(new McpError(\n\t\t\t\t\t\t\"Resource with URI '\" + resourceSpecification.getResource().getUri() + \"' already exists\"));\n\t\t\t}\n\t\t\tlogger.debug(\"Added resource handler: {}\", resourceSpecification.getResource().getUri());\n\t\t\treturn null;\n\t\t}).thenCompose(ignored -> {\n\t\t\tif (this.serverCapabilities.getResources().getListChanged()) {\n\t\t\t\treturn notifyResourcesListChanged();\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 adding resource '{}'\", resourceSpecification.getResource().getUri(), cause);\n\t\t\tthrow new CompletionException(cause);\n\t\t});\n\t}\n\n\tpublic CompletableFuture<Void> removeResource(String resourceUri) {\n\t\tif (resourceUri == null) {","sourceCodeStart":417,"sourceCodeEnd":453,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/arthas-mcp-server/src/main/java/com/taobao/arthas/mcp/server/protocol/server/McpNettyServer.java#L417-L453","documentation":"McpNettyServer.addResource throws McpError (wrapped in CompletionException) when a resource with the same URI is already registered. Resources are stored in a map keyed by Resource.getUri(), and putIfAbsent returning a non-null value means the URI is taken; duplicate URIs would otherwise overwrite each other.","triggerScenarios":"Calling addResource twice with resources whose getUri() is identical; hot reload without removeResource first; two providers contributing the same resource URI.","commonSituations":"Dynamic resource registration on reconnect; resource discovery registering the same URI across modules; URI normalization differences leading to an unexpected exact collision.","solutions":["Call removeResource(uri) before addResource when refreshing.","Check the existing resources map for the URI before adding.","Ensure each resource exposes a unique URI."],"exampleFix":"// before\nserver.addResource(spec); // uri 'jfr://file/123' already exists\n\n// after\nserver.removeResource(\"jfr://file/123\")\n    .thenRun(() -> server.addResource(spec));","handlingStrategy":"validation","validationCode":"String uri = spec.getResource().getUri();\nboolean exists = server.getResources().stream()\n    .anyMatch(r -> r.getResource().getUri().equals(uri));\nif (exists) server.removeResource(uri).join();\nserver.addResource(spec).join();","typeGuard":null,"tryCatchPattern":"try { server.addResource(spec).join(); }\ncatch (CompletionException e) {\n  if (e.getCause() instanceof io.modelcontextprotocol.spec.McpError && e.getCause().getMessage().contains(\"already exists\")) { server.removeResource(uri).thenRun(() -> server.addResource(spec)).join(); }\n  else throw e;\n}","preventionTips":["Check resources map before addResource.","removeResource before re-adding on reload.","Give each resource a unique URI."],"tags":["mcp","arthas-mcp-server","registration","duplicate","resource"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}