alibaba/spring-ai-alibaba · error · IllegalArgumentException

Unsupported DTO type:

Error message

Unsupported DTO type: 

What it means

MessageDTOFactory.toMessage is the inverse of fromMessage: it maps known MessageDTO implementations (ToolRequestMessageDTO, AssistantMessageDTO, UserMessageDTO, ToolResponseMessageDTO) back into Spring AI Message objects. A MessageDTO of any other concrete type — notably ToolRequestConfirmMessageDTO, which exists in the Jackson @JsonSubTypes registry for human-in-the-loop confirmations but has no reverse mapping — triggers this IllegalArgumentException. The exception message includes the offending class name.

Source

Thrown at spring-ai-alibaba-studio/src/main/java/com/alibaba/cloud/ai/agent/studio/dto/messages/MessageDTO.java:130

		public static Message toMessage(MessageDTO dto) {
			if (dto == null) {
				return null;
			}

			if (dto instanceof ToolRequestMessageDTO) {
				return ((ToolRequestMessageDTO) dto).toAssistantMessage();
			}
			else if (dto instanceof AssistantMessageDTO) {
				return ((AssistantMessageDTO) dto).toAssistantMessage();
			}
			else if (dto instanceof UserMessageDTO) {
				return ((UserMessageDTO) dto).toUserMessage();
			}
			else if (dto instanceof ToolResponseMessageDTO) {
				return ((ToolResponseMessageDTO) dto).toToolResponseMessage();
			}
			else {
				throw new IllegalArgumentException(
						"Unsupported DTO type: " + dto.getClass().getName()
				);
			}
		}
	}
}

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Skip ToolRequestConfirmMessageDTO (and other non-reversible DTOs) when rebuilding Messages from DTO maps — filter them out before calling toMessage.
  2. Store the original Message alongside the DTO if you need a faithful round trip through confirm/interruption flows.
  3. If a reverse conversion is genuinely needed, add a branch in MessageDTOFactory.toMessage for the reported DTO type (e.g., convert ToolRequestConfirmMessageDTO back to ToolResponseMessage or drop it).
  4. Never instantiate custom MessageDTO implementations for state that will be converted back via toMessage.

Example fix

// before
Map<String, Message> msgs = new HashMap<>();
dtos.forEach((k, dto) -> msgs.put(k, MessageDTO.MessageDTOFactory.toMessage(dto))); // throws on ToolRequestConfirmMessageDTO

// after
dtos.forEach((k, dto) -> {
    if (dto instanceof ToolRequestConfirmMessageDTO) return; // not convertible to a Message
    msgs.put(k, MessageDTO.MessageDTOFactory.toMessage(dto));
});
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean isConvertibleToMessage(MessageDTO d) {
    return d instanceof ToolRequestMessageDTO || d instanceof AssistantMessageDTO || d instanceof UserMessageDTO || d instanceof ToolResponseMessageDTO;
}

Type guard

static Message safeToMessage(MessageDTO d) {
    if (isConvertibleToMessage(d)) return MessageDTO.MessageDTOFactory.toMessage(d);
    return null; // e.g. ToolRequestConfirmMessageDTO has no reverse mapping
}

Try / catch

try {
    Message m = MessageDTO.MessageDTOFactory.toMessage(dto);
} catch (IllegalArgumentException e) {
    log.warn("Skipping non-reversible DTO: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling MessageDTOFactory.toMessage(dto) with a ToolRequestConfirmMessageDTO (e.g., DTOs deserialized from an interruption/pending-confirm payload), or with any custom MessageDTO implementation, then attempting to rebuild Spring AI Messages from the full DTO set (round-tripping thread values back into graph state).

Common situations: Persisting thread state as DTOs and later converting every DTO back to Messages when resuming a graph; human-in-the-loop flows that stored a tool-confirm DTO in the same map as normal messages; custom MessageDTO subclasses added by application code without updating the factory.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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