{"record":{"id":"e2d4255e8a9248e7","repo":"alibaba/arthas","slug":"prompt-with-name-promptname-not-found","errorCode":null,"errorMessage":"Prompt with name '${promptName}' not found","messagePattern":"Prompt with name '(.+?)' not found","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":573,"sourceCode":"\t\t});\n\t}\n\n\tpublic CompletableFuture<Void> removePrompt(String promptName) {\n\t\tif (promptName == null) {\n\t\t\tCompletableFuture<Void> future = new CompletableFuture<>();\n\t\t\tfuture.completeExceptionally(new McpError(\"Prompt name must not be null\"));\n\t\t\treturn future;\n\t\t}\n\t\tif (this.serverCapabilities.getPrompts() == null) {\n\t\t\tCompletableFuture<Void> future = new CompletableFuture<>();\n\t\t\tfuture.completeExceptionally(new McpError(\"Server must be configured with prompt capabilities\"));\n\t\t\treturn future;\n\t\t}\n\n\t\treturn CompletableFuture.supplyAsync(() -> {\n\t\t\tMcpServerFeatures.PromptSpecification removed = this.prompts.remove(promptName);\n\t\t\tif (removed == null) {\n\t\t\t\tthrow new CompletionException(new McpError(\"Prompt with name '\" + promptName + \"' not found\"));\n\t\t\t}\n\t\t\tlogger.debug(\"Removed prompt handler: {}\", promptName);\n\t\t\treturn null;\n\t\t}).thenCompose(ignored -> {\n\t\t\tif (this.serverCapabilities.getPrompts().getListChanged()) {\n\t\t\t\treturn notifyPromptsListChanged();\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 prompt '{}'\", promptName, cause);\n\t\t\tthrow new CompletionException(cause);\n\t\t});\n\t}\n\n\tpublic CompletableFuture<Void> notifyPromptsListChanged() {\n\t\treturn this.mcpTransportProvider.notifyClients(McpSchema.METHOD_NOTIFICATION_PROMPTS_LIST_CHANGED, null);\n\t}","sourceCodeStart":555,"sourceCodeEnd":591,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/arthas-mcp-server/src/main/java/com/taobao/arthas/mcp/server/protocol/server/McpNettyServer.java#L555-L591","documentation":"Thrown by McpNettyServer.removePrompt() when you unregister a prompt name that is not currently registered. Like removeResource, the server removes from its prompts map and fails the returned future if nothing was found. Prompt names must match exactly the value used at registration time.","triggerScenarios":"Calling removePrompt(promptName) for a name never added, already removed, or misspelled; shutdown hooks that remove prompts the server never owned.","commonSituations":"Idempotent teardown that runs twice; cleanup of prompts registered by a plugin that was never activated; name casing/whitespace mismatch between add and remove.","solutions":["Maintain your own record of registered prompt names and remove only those that exist.","Reuse the exact name string from spec.getPrompt().getName() for removal.","Wrap the returned future with exceptionally(ex -> null) to make removal idempotent for cleanup.","Confirm the target McpNettyServer instance is the one that registered the prompt."],"exampleFix":"// before\nserver.removePrompt(name).join(); // throws if absent\n\n// after\nSet<String> registeredPrompts = ConcurrentHashMap.newKeySet();\nserver.addPrompt(spec);\nregisteredPrompts.add(name);\nif (registeredPrompts.remove(name)) {\n    server.removePrompt(name).join();\n}","handlingStrategy":"validation","validationCode":"Set<String> registeredPrompts = ConcurrentHashMap.newKeySet();\n// on add: registeredPrompts.add(name);\nif (registeredPrompts.remove(promptName)) {\n    server.removePrompt(promptName).join();\n}","typeGuard":null,"tryCatchPattern":"server.removePrompt(promptName)\n    .exceptionally(ex -> {\n        Throwable c = ex instanceof CompletionException ? ex.getCause() : ex;\n        if (c instanceof McpError me && me.getMessage().contains(\"not found\")) {\n            return null;\n        }\n        throw new CompletionException(c);\n    })\n    .join();","preventionTips":["Track registered prompt names locally.","Make teardown idempotent with exceptionally.","Reuse the exact name string from addPrompt."],"tags":["mcp","prompt","dynamic-registration","stateful-server","java"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}