fix(reply): send the parent's RFC msg-id in In-Reply-To, not its JMAP id - #35
Open
lucletoffe wants to merge 1 commit into
Open
fix(reply): send the parent's RFC msg-id in In-Reply-To, not its JMAP id#35lucletoffe wants to merge 1 commit into
lucletoffe wants to merge 1 commit into
Conversation
Replying put `email.id` — the server-local JMAP handle, e.g. `gos2aabtux` — into In-Reply-To/References. No recipient can match that against any Message-ID, so the conversation splits in two: the original sits alone in its thread while the reply (and everything answering it) starts a fresh one. Proven against a live Stalwart account: the reply carried `In-Reply-To: gos2aabtux` and landed in thread `btuz` while its parent stayed in `btux` — Stalwart hashes the referenced msg-ids at ingest and found no match. Fetch `messageId`/`inReplyTo`/`references` with the full email and build the headers from them (bracketed, ancestors first, parent closing the chain). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FTRyrFCR2N9qkpKK37GgWb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
Replying puts
email.id— the server-local JMAP handle, e.g.gos2aabtux— intoIn-Reply-ToandReferences(EmailThreadScreen.tsx,navigateCompose). That id ismeaningless outside the account it came from: it is not an RFC 5322 msg-id, so no client
and no server can match it against the parent's
Message-ID.The conversation therefore splits in two: the original message sits alone in its thread,
while the reply — and everything that answers the reply — starts a fresh one.
Proof
Observed against a live Stalwart account (ids abbreviated):
btuxbtuzgos2aabtux← JMAP id of #1btuz18c72125…@mail-1Server side this is correct behaviour: Stalwart hashes the referenced msg-ids at ingest
(
crates/email/src/message/ingest.rs::find_thread_id), finds no match, and files the replyunder a new thread. The webmail builds these headers correctly, so the split only happens
to conversations replied to from mobile.
The fix
src/lib/email-threading.ts:computeReplyThreadingHeaders()builds the pair from theparent's
messageIdandreferences— bracketed, ancestors first, parent closing thechain, de-duped (RFC 5322 §3.6.4).
messageId/inReplyTo/referencesadded to theEmailtype and toEMAIL_FULL_PROPERTIESso they are actually fetched (JMAP returns them as bare ids,RFC 8621 §4.1.2.3).
navigateComposeuses it instead ofemail.id.Replies to a message whose parent has no
Message-IDnow send no threading headers at all,rather than a header that is actively wrong.
Tests
src/lib/__tests__/email-threading.test.ts— 5 cases: no msg-id, bracketing, ancestor chain,de-dupe, ids that already carry angle brackets.
npx tsc --noEmitclean; full suite 364 passed(
src/stores/__tests__/auth-store.test.tsfails to import onmaintoo — pre-existing, unrelated).