alibaba/spring-ai-alibaba · error · UnsupportedOperationException

Currently Spring AI ToolResponseMessage only supports text…

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.

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.

Appendix: 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)