Skip to content

fix(email): send IMAP ID extension to support 163/NetEase mailbox#22528

Closed
wesleysimplicio wants to merge 2 commits into
NousResearch:mainfrom
wesleysimplicio:fix/email-imap-id-extension-163
Closed

fix(email): send IMAP ID extension to support 163/NetEase mailbox#22528
wesleysimplicio wants to merge 2 commits into
NousResearch:mainfrom
wesleysimplicio:fix/email-imap-id-extension-163

Conversation

@wesleysimplicio

Copy link
Copy Markdown
Contributor

Summary

163/NetEase IMAP servers reject every UID SEARCH/UID FETCH with BYE Unsafe Login unless the client first identifies itself via the RFC 2971 ID command after LOGIN. Without this, the email gateway authenticates OK but then fails on the very first poll and the connection is torn down — repeatedly.

This PR sends the ID payload best-effort after each imap.login():

  • EmailAdapter.connect() — initial connection check
  • EmailAdapter._fetch_new_messages() — every poll cycle (opens its own session)

The send is wrapped in try/except so non-supporting IMAP servers (Gmail, Outlook, Fastmail, Yahoo, …) keep working unchanged — they either honor the command silently or reply BAD, which we log at debug.

Why a tiny helper

_send_imap_id(imap) lives at module level so it can be tested in isolation and reused by both login sites without duplicating the literal payload.

Test plan

New TestImapIdExtensionForNetEase class covers:

  • test_connect_sends_imap_id_after_login — asserts xatom("ID", ...) is called after LOGIN from connect(), payload contains client name
  • test_fetch_new_messages_sends_imap_id_after_login — same assertion for the polling path (which opens a separate IMAP session)
  • test_send_imap_id_swallows_errors_for_non_supporting_servers — feeds the helper a server that raises on xatom, verifies it does not propagate

Stash-verified: all three tests fail without the source change, pass with it. Existing 60-test test_email.py suite continues to pass.

Closes #22271

🤖 Generated with Claude Code

163/NetEase IMAP servers reject every UID SEARCH/FETCH with `BYE Unsafe
Login` unless the client first identifies itself via the RFC 2971 ID
command after LOGIN.  Without this, the email gateway logs in OK but
then fails on the very first poll and the connection is torn down.

Send the ID payload best-effort after both `imap.login()` sites
(`EmailAdapter.connect` and `_fetch_new_messages`).  Failures are
swallowed at debug level so non-supporting IMAP servers (Gmail,
Outlook, Fastmail, Yahoo, etc.) keep working unchanged.

Closes NousResearch#22271
Copilot AI review requested due to automatic review settings May 9, 2026 11:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds best-effort support for NetEase/163 IMAP servers that require an RFC 2971 ID command after LOGIN, preventing immediate BYE Unsafe Login disconnects during subsequent UID SEARCH/UID FETCH operations in the email gateway.

Changes:

  • Introduces a reusable _send_imap_id(imap) helper that attempts to send an IMAP ID payload and swallows failures for non-supporting servers.
  • Calls _send_imap_id() immediately after imap.login() in both EmailAdapter.connect() and EmailAdapter._fetch_new_messages().
  • Adds regression tests asserting ID is sent after login in both the initial connect path and the polling path, plus a test ensuring failures are non-fatal.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
gateway/platforms/email.py Adds _send_imap_id() and invokes it after IMAP login in both connection-check and polling sessions.
tests/gateway/test_email.py Adds regression tests for sending RFC 2971 ID after login and for swallowing unsupported-server errors.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +77 to +82
imap.xatom(
"ID",
'("name" "hermes-agent" "version" "1.0" '
'"vendor" "NousResearch" '
'"support-email" "noreply@nousresearch.com")',
)
@teknium1

teknium1 commented May 9, 2026

Copy link
Copy Markdown
Contributor

Merged via salvage PR #22796. salvage cherry-picked your commits; authorship preserved. Thanks for the contribution!

@teknium1 teknium1 closed this May 9, 2026
@alt-glitch alt-glitch added type/bug Something isn't working platform/email Email (IMAP/SMTP) adapter P2 Medium — degraded but workaround exists labels May 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Medium — degraded but workaround exists platform/email Email (IMAP/SMTP) adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

163 mailbox IMAP connection fails - Missing IMAP ID extension support

4 participants