{"record":{"id":"5cf777ace9cab860","repo":"alibaba/spring-ai-alibaba","slug":"unsupported-message-type-5cf777","errorCode":null,"errorMessage":"Unsupported message type: ","messagePattern":"Unsupported message type: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-studio/src/main/java/com/alibaba/cloud/ai/agent/studio/dto/messages/MessageDTO.java","lineNumber":92,"sourceCode":"\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif (message instanceof AssistantMessage assistantMessage) {\n\t\t\t\tif (assistantMessage.hasToolCalls()) {\n\t\t\t\t\treturn new ToolRequestMessageDTO(assistantMessage);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn new AssistantMessageDTO(assistantMessage);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (message instanceof UserMessage) {\n\t\t\t\treturn new UserMessageDTO((UserMessage) message);\n\t\t\t}\n\t\t\telse if (message instanceof ToolResponseMessage) {\n\t\t\t\treturn new ToolResponseMessageDTO((ToolResponseMessage) message);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\"Unsupported message type: \" + message.getClass().getName()\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Convert InterruptionMetadata to ToolRequestMessageDTO.\n\t\t * This is a specialized method for handling interruption metadata from agent execution.\n\t\t */\n\t\tpublic static ToolRequestConfirmMessageDTO fromInterruptionMetadata(InterruptionMetadata interruptionMetadata) {\n\t\t\tif (interruptionMetadata == null) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn new ToolRequestConfirmMessageDTO(interruptionMetadata);\n\t\t}\n\n\t\t/**\n\t\t * Convert DTO to Spring AI Message.","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-studio/src/main/java/com/alibaba/cloud/ai/agent/studio/dto/messages/MessageDTO.java#L74-L110","documentation":"MessageDTOFactory.fromMessage converts Spring AI Message objects (AssistantMessage, UserMessage, ToolResponseMessage) into UI DTOs; AgentInstructionMessage and null are handled specially. Any other Message subtype has no DTO mapping, so an IllegalArgumentException naming the concrete class is thrown. It exists because Spring AI can produce message types (notably SystemMessage and custom subclasses) that the Studio transcript layer deliberately does not render.","triggerScenarios":"Calling MessageDTOFactory.fromMessage(message) with a Message that is none of AssistantMessage (with or without tool calls), UserMessage, ToolResponseMessage, or AgentInstructionMessage — most commonly a SystemMessage, or a custom Message subclass from a newer/patched Spring AI version, fed from graph state or history into the Studio thread/view pipeline.","commonSituations":"Graph state or chat history contains a SystemMessage (system prompts) that reaches the DTO conversion when rendering a thread; upgrading Spring AI introduces new Message implementations not yet mapped; custom framework code inserts its own Message subclass into state; tests feeding raw SystemMessage into the converter.","solutions":["Filter SystemMessage and other unmapped types out of the message list before calling fromMessage (skip or log them).","Extend the conversion switch to handle the concrete type reported in the exception message (e.g., add a branch mapping SystemMessage to null or a dedicated DTO).","Check your agent/graph construction: avoid injecting unmapped Message types into state keys that Studio serializes.","If a new Spring AI version added the type, file/apply an update to MessageDTOFactory's instanceof chain to cover it."],"exampleFix":"// before\nif (message instanceof AgentInstructionMessage) { return null; }\n...\nelse { throw new IllegalArgumentException(\"Unsupported message type: \" + ...); }\n\n// after: tolerate system prompts by hiding them like instructions\nif (message instanceof AgentInstructionMessage || message instanceof SystemMessage) {\n    return null; // not rendered in the UI transcript\n}","handlingStrategy":"type-guard","validationCode":"static boolean isConvertibleToDto(Message m) {\n    return m instanceof AssistantMessage || m instanceof UserMessage || m instanceof ToolResponseMessage || m instanceof AgentInstructionMessage;\n}","typeGuard":"static MessageDTO safeFromMessage(Message m) {\n    if (m instanceof AssistantMessage || m instanceof UserMessage || m instanceof ToolResponseMessage) {\n        return MessageDTO.MessageDTOFactory.fromMessage(m);\n    }\n    return null; // skip SystemMessage and unknown subtypes\n}","tryCatchPattern":"try {\n    MessageDTO dto = MessageDTO.MessageDTOFactory.fromMessage(message);\n} catch (IllegalArgumentException e) {\n    log.warn(\"Skipping non-renderable message: {}\", e.getMessage());\n}","preventionTips":["Filter out SystemMessage and custom Message subtypes before converting.","After upgrading Spring AI, re-check for new Message implementations in graph state.","Keep unmapped message types out of state keys that Studio serializes."],"tags":["dto","type-mapping","spring-ai","messages"],"backgroundTag":"unsupported-operation","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}