1.9 KiB
1.9 KiB
Email triage state file — critical post-migration check
The ~/.hermes/email_triage/state.json file tracks processed IMAP UIDs. Without it, the IMAP triage cron job treats every inbox message as new on first run.
Migration pitfall
Symptom: After a ~/.hermes/ migration, the hourly IMAP triage cron fails with RuntimeError: Context length exceeded (X tokens). Cannot compress further.
Root cause: state.json was not in the tarball (or was excluded by a custom exclude pattern). On first run, the script processes the entire inbox — often 3000+ messages — which blows the context window.
Fix:
-
Check if the old server still has the file:
scp root@old-server-ip:/root/.hermes/email_triage/state.json /root/.hermes/email_triage/ -
If the standby box has it, grab it from there:
scp root@standby-ip:/root/.hermes/email_triage/state.json /root/.hermes/email_triage/ -
If both copies are gone, initialize state by marking all old UIDs as processed:
import imaplib, ssl, json, datetime ctx = ssl.create_default_context() m = imaplib.IMAP4_SSL('mail.germainebrown.com', 993, ssl_context=ctx) m.login('g@germainebrown.com', open('/root/.config/himalaya/g-germainebrown.pass').read().strip()) m.select('INBOX') status, data = m.uid('search', None, 'ALL') uids = data[0].split() if data[0] else [] processed = {} if len(uids) > 50: recent = uids[-50:] old = uids[:-50] for uid in old: processed[uid.decode()] = {'summary': 'pre-migration-rebuild', 'decision': 'skip', 'timestamp': '2026-07-05T10:00:00Z'} state = {'processed_uids': processed, 'created_at': datetime.datetime.now(datetime.timezone.utc).isoformat()} # Write to ~/.hermes/email_triage/state.json
Prevention
- Add
email_triage/state.jsonandemail_triage/actions.jsonlto the migration manifest. - Verify these files exist before turning off the old server.