email: fix backfill crash on emails with no Reply-To; Sync now retries errored mailboxes (v0.1.0:62)

insert_email's recipients loop did `for a in parsed.get(kind, [])`, but the parser sets
reply_to=None when there is no Reply-To header, so .get returns None (key present) and the
loop raised 'NoneType' object is not iterable — aborting the entire Gmail backfill on the
first such email (i.e. almost immediately). Fixed with `or []`. Regression test
test_insert_email.py (reply_to=None, all-None recipients, happy path).

Because the scheduler intentionally skips error-status accounts (no retry storms), an
errored mailbox would never resume on its own. "Sync now" now clears error status first,
so it is an explicit retry; backfill resumes from its saved cursor and dedups by
Message-ID, so nothing is re-captured.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Keysat
2026-06-06 12:41:06 -05:00
parent 2cb476e36b
commit ea036f49a6
6 changed files with 126 additions and 5 deletions
+19
View File
@@ -0,0 +1,19 @@
import { VersionInfo } from '@start9labs/start-sdk'
// Bugfix: the Gmail backfill crashed with "'NoneType' object is not iterable" on any
// email with no Reply-To header (parsed reply_to=None hit `for a in parsed.get(kind, [])`,
// which returns None when the key is present-but-None) — aborting the whole backfill.
// Fixed with `or []`. Also: "Sync now" now clears error status so a previously-errored
// mailbox is retried (the scheduler deliberately skips error accounts); backfill resumes
// from its saved cursor and dedups by Message-ID. No schema migration.
export const v_0_1_0_62 = VersionInfo.of({
version: '0.1.0:62',
releaseNotes: {
en_US: [
'Fixes a bug that stopped the Gmail backfill on any email without a Reply-To header',
'(most of them), which is why capture stalled. After updating, open Email Capture and',
'click Sync now to resume — it picks up where it left off and will not double-capture.',
].join(' '),
},
migrations: { up: async () => {}, down: async () => {} },
})