alibaba/arthas · error · McpError
Prompt with name '${promptName}' not found
Error message
Prompt with name '${promptName}' not found What it means
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.
Source
Thrown at arthas-mcp-server/src/main/java/com/taobao/arthas/mcp/server/protocol/server/McpNettyServer.java:573
});
}
public CompletableFuture<Void> removePrompt(String promptName) {
if (promptName == null) {
CompletableFuture<Void> future = new CompletableFuture<>();
future.completeExceptionally(new McpError("Prompt name must not be null"));
return future;
}
if (this.serverCapabilities.getPrompts() == null) {
CompletableFuture<Void> future = new CompletableFuture<>();
future.completeExceptionally(new McpError("Server must be configured with prompt capabilities"));
return future;
}
return CompletableFuture.supplyAsync(() -> {
McpServerFeatures.PromptSpecification removed = this.prompts.remove(promptName);
if (removed == null) {
throw new CompletionException(new McpError("Prompt with name '" + promptName + "' not found"));
}
logger.debug("Removed prompt handler: {}", promptName);
return null;
}).thenCompose(ignored -> {
if (this.serverCapabilities.getPrompts().getListChanged()) {
return notifyPromptsListChanged();
}
return CompletableFuture.completedFuture(null);
}).exceptionally(ex -> {
Throwable cause = ex instanceof CompletionException ? ex.getCause() : ex;
logger.error("Error while removing prompt '{}'", promptName, cause);
throw new CompletionException(cause);
});
}
public CompletableFuture<Void> notifyPromptsListChanged() {
return this.mcpTransportProvider.notifyClients(McpSchema.METHOD_NOTIFICATION_PROMPTS_LIST_CHANGED, null);
}View on GitHub (pinned to 21cf2e9ba5)
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.
Example fix
// before
server.removePrompt(name).join(); // throws if absent
// after
Set<String> registeredPrompts = ConcurrentHashMap.newKeySet();
server.addPrompt(spec);
registeredPrompts.add(name);
if (registeredPrompts.remove(name)) {
server.removePrompt(name).join();
} Defensive patterns
Strategy: validation
Validate before calling
Set<String> registeredPrompts = ConcurrentHashMap.newKeySet();
// on add: registeredPrompts.add(name);
if (registeredPrompts.remove(promptName)) {
server.removePrompt(promptName).join();
} Try / catch
server.removePrompt(promptName)
.exceptionally(ex -> {
Throwable c = ex instanceof CompletionException ? ex.getCause() : ex;
if (c instanceof McpError me && me.getMessage().contains("not found")) {
return null;
}
throw new CompletionException(c);
})
.join(); Prevention
- Track registered prompt names locally.
- Make teardown idempotent with exceptionally.
- Reuse the exact name string from addPrompt.
When it happens
Trigger: Calling removePrompt(promptName) for a name never added, already removed, or misspelled; shutdown hooks that remove prompts the server never owned.
Common situations: Idempotent teardown that runs twice; cleanup of prompts registered by a plugin that was never activated; name casing/whitespace mismatch between add and remove.
Related errors
- Prompt with name '${promptName}' already exists
- Resource with URI '${resourceUri}' not found
- Prompt with name '{}' already exists
- Prompt with name '{}' not found
- Tool with name '{}' already exists
AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14).
Data as JSON: /api/errors/e2d4255e8a9248e7.
Report an issue: GitHub.