Make label: search read the table that records labels

FixEmailService
Shipped
September 2, 2026 at 5:54 AM UTC
Author
Kamo
Commit
f7b5c7c

The clause tested si.label_ids, an array column on the search index. Nothing has ever written it — labelling a message inserts into email_metadata.message_labels, and neither the full indexer nor the folder-listing path sets the column. In production it is populated on zero of 547 rows, so the condition was an empty array containment test: false for every message, for every member. It was wrong a second time, and that one threw. The operand is whatever follows label: in the search box, which is a label's NAME — the backend's own suggestion says "Filter by label name", and the advanced panel builds label:<free text>. The clause cast that to UUID, so any real label name failed with invalid input syntax for type uuid: "work" verified against the live database. SearchService catches an index-search failure and falls back to IMAP, so a member searching label:work got no error and no labelled mail — just whatever IMAP made of the word, marked "(via IMAP)". So it now asks message_labels, resolving the name against the searching member's own labels. Case-insensitively: the name is typed by hand into a free-text box, and "Work" and "work" are one label to everyone except SQL. Scoping matters on both sides — the message must be the member's and so must the label, because label names are per-member and two members may each have a "Work". The replacement was run against the live database and returns rows rather than erroring. It matches nothing yet for a plainer reason than the bug: no member has created a label at all, so labels and message_labels are both empty.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing