Skip to content

Fix Email/query hasAttachment for binary attachments#2778

Open
onevcat wants to merge 1 commit intostalwartlabs:mainfrom
onevcat:fix-hasattachment-query
Open

Fix Email/query hasAttachment for binary attachments#2778
onevcat wants to merge 1 commit intostalwartlabs:mainfrom
onevcat:fix-hasattachment-query

Conversation

@onevcat
Copy link
Copy Markdown

@onevcat onevcat commented Feb 9, 2026

Problem

Email/get reports hasAttachment: true for messages that include attachments, but Email/query with filter {hasAttachment: true} can return an empty result set for the same messages.

In practice this shows up with messages that have binary attachments (e.g. application/octet-stream) where Stalwart does not extract/index attachment text.

Investigation / root cause

During investigation (triggered from xin's JMAP integration tests), we observed:

  • Email/get for a message with an attachment returns hasAttachment: true and attachmentsCount > 0.
  • Email/query with filter: {hasAttachment: true} returns ids: [].

The root cause is that HasAttachment was indexed based on whether the full-text Attachment search field exists:

  • EmailSearchField::Attachment is only present when attachment text is indexed.
  • This is not equivalent to “message has attachments”.

Meanwhile Email/get derives hasAttachment from the message metadata bit (MESSAGE_HAS_ATTACHMENT, stored in rcvd_attach).

Fix

Index EmailSearchField::HasAttachment from the message metadata bit (MESSAGE_HAS_ATTACHMENT) so Email/query matches Email/get semantics.

Tests

Add a regression test that imports an email with a binary attachment (application/octet-stream) and asserts that it is returned by Email/query with hasAttachment: true.

Local testing

cargo test -q -p email -p jmap -p jmap_proto

(Full -p tests requires the fdb_c library on my local machine; CI should run the full suite.)

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Feb 9, 2026

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants