alibaba/spring-ai-alibaba · error · UnsupportedOperationException

Currently Spring AI ToolResponseMessage only supports text t

Error message

Currently Spring AI ToolResponseMessage only supports text type, that's why the return type of this method is String. More types like image/audio/video/file can be supported in the future.

What it means

MessageToolCallResultConverter.convert throws UnsupportedOperationException when a tool returns an AssistantMessage that has media (image/audio/video/file) content but no text, because Spring AI's ToolResponseMessage only supports String (text) tool results.

Source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/MessageToolCallResultConverter.java:47

import org.slf4j.LoggerFactory;

public class MessageToolCallResultConverter implements ToolCallResultConverter {

	private static final Logger logger = LoggerFactory.getLogger(MessageToolCallResultConverter.class);

	/**
	 * Currently Spring AI ToolResponseMessage only supports text type, that's why the return type of this method is String.
	 * More types like image/audio/video/file can be supported in the future.
	 */
	public String convert(@Nullable Object result, @Nullable Type returnType) {
		if (returnType == Void.TYPE) {
			logger.debug("The tool has no return type. Converting to conventional response.");
			return JsonParser.toJson("Done");
		} else if (result instanceof AssistantMessage assistantMessage) {
			if (StringUtils.hasLength(assistantMessage.getText())) {
				return assistantMessage.getText();
			} else if (CollectionUtils.isNotEmpty(assistantMessage.getMedia())) {
				throw new UnsupportedOperationException("Currently Spring AI ToolResponseMessage only supports text type, that's why the return type of this method is String. More types like image/audio/video/file can be supported in the future.");
			}
			logger.warn("The tool returned an empty AssistantMessage. Converting to conventional response.");
			return JsonParser.toJson("Done");
		} else {
			logger.debug("Converting tool result to JSON.");
			return JsonParser.toJson(result);
		}
	}
}

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Return a String from the tool (e.g. a URL, base64, or textual description of the media) instead of a media-bearing AssistantMessage.
  2. If returning AssistantMessage, ensure setText/description carries non-empty text alongside media.
  3. Return a Map/POJO and let the converter JSON-serialize it instead of using AssistantMessage.

Example fix

// before
return new AssistantMessage("", List.of(new Media(MimeTypeUtils.IMAGE_PNG, url)));
// after
return "Generated image available at " + url;
Defensive patterns

Strategy: type-guard

Validate before calling

if (result instanceof AssistantMessage am && !am.hasText() && CollectionUtils.isNotEmpty(am.getMedia())) {
    throw new IllegalStateException("Tool returns media-only AssistantMessage; return a String instead");
}

Type guard

static boolean isTextOnlyResult(Object r) {
    return !(r instanceof AssistantMessage am) || (StringUtils.hasLength(am.getText()) || CollectionUtils.isEmpty(am.getMedia()));
}

Try / catch

try { result = tool.call(args, ctx); } catch (UnsupportedOperationException e) { result = describeMediaAsText(toolResult); }

Prevention

When it happens

Trigger: A @Tool method (or tool callback) returns an AssistantMessage whose media list is non-empty and whose text is empty; the converter then cannot produce a String result for the ToolResponseMessage.

Common situations: Wrapping a multimodal model output or generated image in an AssistantMessage and returning it from a tool; porting tools that returned richer content types from other frameworks.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/bf0360702d592d81. Report an issue: GitHub.