Email: an incoming reply with a different Subject is appended to the old conversation, so agent replies are sent to the customer under an unrelated Subject
Describe the bug
Imap::ImapMailbox#find_or_create_conversation resolves the conversation for an incoming e-mail only from In-Reply-To / References. The Subject is read once, at conversation creation, into additional_attributes.mail_subject, and is never compared again.
A very common customer habit — especially on Outlook/Exchange — is to open a new request by hitting Reply on the last e-mail and editing the Subject, instead of composing a new message. Their mail client then correctly emits In-Reply-To/References pointing at the previous message (RFC 5322 §3.6.4 requires exactly that), while the Subject announces a different topic. Chatwoot follows the headers, ignores the Subject, and appends the new request to the old conversation.
The user-visible defect is outbound. ConversationReplyMailer#mail_subject sends "Re: " + @conversation.additional_attributes['mail_subject'], i.e. the subject of the first e-mail of the conversation, forever. So once a conversation has absorbed a second topic, every agent reply about topic B is delivered to the customer under topic A's subject. Chatwoot is emitting a Subject header that contradicts the body it is attached to.
On one of our e-mail inboxes a single conversation accumulated six unrelated requests over two and a half months, each opened by replying to the previous one and changing the Subject. Every agent reply for those two and a half months went out under the first request's subject. The customer complained twice that our answers referenced the wrong case — which is how we found this.
Secondary effects of the same merge: the N unrelated requests share one status, one assignee, one team, one label set, one CSAT and one resolution time, and reporting counts them as a single conversation.
We are filing this as a bug rather than a feature request because the observable behaviour is Chatwoot sending the customer an e-mail whose Subject belongs to a different request. It is not a preference about how conversations should be grouped.
To Reproduce
Any IMAP-based e-mail inbox (plain IMAP, Google or Microsoft — they all share Imap::ImapMailbox).
- Connect an e-mail inbox via IMAP.
- From a customer address, send
Subject: Request Ato that inbox. Chatwoot creates conversation#1withadditional_attributes.mail_subject = "Request A". - Reply to it from the Chatwoot dashboard. The outgoing e-mail has
Subject: Re: Request A. - In the customer's mail client, hit Reply on that e-mail, change the Subject to
Request B, and send. The client keepsIn-Reply-To/Referencespointing at the Chatwoot message. - Observed: the e-mail is appended to conversation
#1. There is no new conversation, and nothing in the UI indicates the topic changed. - Reply from the dashboard to what is now a thread about Request B. Observed: the outgoing e-mail carries
Subject: Re: Request A.
Step 6 is the defect the customer sees. Steps 4–5 are its cause.
Repeating step 4 on top of each new topic chains indefinitely: we reproduced a conversation with six distinct subjects this way.
Expected behavior
An incoming e-mail whose Subject differs from the conversation's should start a new conversation, even when In-Reply-To/References point into an existing one. The headers remain the only way a candidate conversation is found; the Subject confirms or vetoes it.
And in no case should Chatwoot send a reply under a Subject that belongs to a different request.
How other providers do it?
- Gmail — Google's own documentation: "A conversation breaks off into a new conversation when the subject line changes, or the conversation gets to more than 100 emails." The mechanism is stated even more plainly in the Gmail API: to add a message to an existing thread, "The
ReferencesandIn-Reply-Toheaders must be set in compliance with the RFC 2822 standard" and "TheSubjectheaders must match." Headers and subject — which is exactly what this report asks for. - Outlook / Exchange — the grouping key is
PidTagConversationTopic, the normalised subject (MAPI docs: "All messages that have the same value for PR_CONVERSATION_TOPIC can be sorted on this property…"). Editing the subject of a reply yields a newConversationTopicand a new conversation.
The practical consequence is worth stating plainly: in the reported case the six topics are already six separate threads in the customer's own Outlook, and would be six threads for any Gmail reader. Chatwoot is the only participant in the exchange that shows them as one, and the only one sending replies under the wrong subject.
Environment
Kubernetes
Cloud Provider
GCP
Platform
Browser
Operating system
No response
Browser and version
No response
Docker (if applicable)
No response
Additional context
Suggested fix
Keep the header lookup as the only way a candidate conversation is found, and add a subject check before accepting it — i.e. in Imap::ImapMailbox, wrap find_conversation_by_in_reply_to and find_conversation_by_reference_ids so that a candidate whose mail_subject differs from the incoming Subject is discarded and the existing Conversation.create! runs.
Related issues — and why this ask is narrower
- #14993 (Group emails with the same subject into a single conversation thread) is the opposite direction: it asks for the Subject to create a link when headers are absent. That is a merge heuristic and a genuine feature — and a risky one, since the same subject does not imply the same case. This report is the strict dual and is much narrower: the Subject never creates a link here, it only vetoes one that the headers already made. Fixing this neither implements nor blocks #14993;
- #15793 (Optional conversation subject/title, defaulting to the first email's subject) addresses the same underlying pain from the UI side — merged conversations are indistinguishable in the list. An editable title makes a merged conversation easier to label, but the merge still happens and the outbound
Subjectstays wrong, so it does not cover this report.
Additional Context
Version. Verified on v4.14.2-ce and v4.17.0-ce; app/mailboxes/imap/imap_mailbox.rb is byte-identical (sha256 cb35988e0b253d5bfdc5fa16374e154494979d77bc7d1d53c1d6022dcebf5193) on develop as of 2026-09-17, so this applies to current develop.
Environment. Self-hosted CE on Kubernetes (GCP), e-mail inbox via Gmail OAuth/IMAP.
Source: chatwoot/chatwoot