diff --git a/mirai-core/src/main/java/net/mamoe/mirai/message/Message.kt b/mirai-core/src/main/java/net/mamoe/mirai/message/Message.kt
index a6f31088c..244b6a8e0 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/message/Message.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/message/Message.kt
@@ -104,6 +104,12 @@ abstract class Message {
      * @return message connected
      */
     open fun concat(tail: Message): MessageChain {
+        if (tail is MessageChain) {
+            return MessageChain(this).let {
+                tail.list.forEach { child -> it.concat(child) }
+                it
+            }
+        }
         return MessageChain(this, Objects.requireNonNull(tail))
     }
 
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/MessageChain.kt b/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/MessageChain.kt
index 3f6696db3..27e9042fb 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/MessageChain.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/MessageChain.kt
@@ -11,6 +11,9 @@ import java.util.stream.Stream
 class MessageChain : Message {
     override val type: Int = MessageId.CHAIN
 
+    /**
+     * Elements will not be instances of [MessageChain]
+     */
     val list: MutableList<Message> = Collections.synchronizedList(LinkedList<Message>())
 
     constructor(head: Message, tail: Message) {
@@ -58,6 +61,10 @@ class MessageChain : Message {
     }
 
     override fun concat(tail: Message): MessageChain {
+        if (tail is MessageChain) {
+            tail.list.forEach { child -> this.concat(child) }
+            return this
+        }
         this.list.add(tail)
         clearToStringCache()
         return this