Skip to content

test(conv): fix flaky IMAP backfill test by ordering the channel lookup - #1133

Merged
kmonsoe merged 1 commit into
mainfrom
fix/email-test-channel-order
Oct 1, 2026
Merged

kmonsoe merged 1 commit into
mainfrom
fix/email-test-channel-order

Conversation

@kmonsoe

@kmonsoe kmonsoe commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

What

Fixes the flaky a newly connected mailbox imports only the last backfillDays of existing mail test added in #1130. It failed on #1132 on both attempts, with expected 1 to be 2 on messagesIngested and expected {} to deeply equal { lastUid: 3, uidValidity: '1' } on the cursor.

Why it flaked

imapChannelFor returned rows[0] from a query with no ORDER BY. From the draft_only test onwards, the suite's org holds two IMAP channels: the original support inbox and "Acme Outreach".

Postgres returns unordered rows in heap order, and an UPDATE writes a new tuple version, which can move a row behind its neighbours. The backfill test:

  1. looks up the channel, deletes its cursor and sets inbound.backfillDays with an UPDATE;
  2. looks the channel up again, and that UPDATE can now make the other channel come back first;
  3. ticks that other channel, whose cursor was never reset, so only 1 message is ingested;
  4. reads the cursor of the first channel, which was deleted and never rewritten, so it gets {}.

The flip is easy to reproduce on its own:

CREATE TEMP TABLE ch (id text, config jsonb);
INSERT INTO ch VALUES ('support', '{}'), ('outreach', '{}');
SELECT id FROM ch;  -- support, outreach
UPDATE ch SET config = jsonb_set(config, '{backfillDays}', '7') WHERE id = 'support';
SELECT id FROM ch;  -- outreach, support

Fix

Order the helper's query by created_at, id, so every lookup returns the original support channel, which is what these tests already got in the usual case. This changes test code only; the backfill logic in email-adapter.ts is not involved.

Testing

email.integration.test.ts passes 23/23, three runs in a row locally. Typecheck and lint pass.

🤖 Generated with Claude Code

imapChannelFor returned rows[0] of an unordered query, but from the
draft_only test onwards the org holds two IMAP channels (the original
support inbox and "Acme Outreach"). Postgres returns rows in heap order,
and an UPDATE rewrites the tuple, so the backfill test's own config
update could flip which channel the next lookup returned. It then reset
the cursor and set backfillDays on one channel but ticked the other,
ingesting 1 message instead of 2 and reading back an empty cursor.

Order by created_at, id so every lookup returns the original channel.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@kmonsoe
kmonsoe merged commit ee4acee into main Oct 1, 2026
7 checks passed
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.

1 participant