alibaba/arthas · error · McpError

Prompt with name '{}' not found

Error message

Prompt with name '{}' not found

What it means

Thrown by McpStatelessNettyServer.removePrompt() when dynamically unregistering a prompt name not present in the stateless server's prompts map. The async removal returns null and fails the returned CompletableFuture with this McpError wrapped in CompletionException.

Source

Thrown at arthas-mcp-server/src/main/java/com/taobao/arthas/mcp/server/protocol/server/McpStatelessNettyServer.java:413

	public CompletableFuture<Void> removePrompt(String promptName) {
		if (promptName == null || promptName.isEmpty()) {
			CompletableFuture<Void> future = new CompletableFuture<>();
			future.completeExceptionally(new McpError("Prompt name must not be null or empty"));
			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
				.runAsync(() -> {
					McpStatelessServerFeatures.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);
				})
				.exceptionally(ex -> {
					Throwable cause = (ex instanceof CompletionException) ? ex.getCause() : ex;
					logger.error("Error while removing prompt '{}'", promptName, cause);
					throw new CompletionException(cause);
				});
	}


	private McpStatelessRequestHandler<McpSchema.ListPromptsResult> promptsListRequestHandler() {
		return (exchange, commandContext, params) -> {
			List<McpSchema.Prompt> promptList = new ArrayList<>();
			for (McpStatelessServerFeatures.PromptSpecification promptSpec : this.prompts.values()) {
				promptList.add(promptSpec.getPrompt());
			}
			return CompletableFuture.completedFuture(new McpSchema.ListPromptsResult(promptList, null));

View on GitHub (pinned to 21cf2e9ba5)

Solutions

  1. Track registered prompt names and remove only those present.
  2. Make teardown idempotent with exceptionally(ex -> null).
  3. Reuse the exact name string from registration.
  4. Verify you operate on the McpStatelessNettyServer that owns the prompt.

Example fix

// before
statelessServer.removePrompt(name).join(); // throws if absent

// after
statelessServer.removePrompt(name)
    .exceptionally(ex -> null)
    .join(); // idempotent cleanup
Defensive patterns

Strategy: validation

Validate before calling

Set<String> addedPrompts = ConcurrentHashMap.newKeySet();
// on add: addedPrompts.add(name);
if (addedPrompts.remove(promptName)) {
    statelessServer.removePrompt(promptName).join();
}

Try / catch

statelessServer.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

When it happens

Trigger: Calling removePrompt(name) for a name never added, already removed, or misspelled on a stateless server.

Common situations: Double teardown; cleanup of a prompt that never registered; name mismatch; wrong server instance.

Related errors


AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14). Data as JSON: /api/errors/82ba25edd577174f. Report an issue: GitHub.