Fix: _batch_fetch_headers UID parsing for aioimaplib response format#111
Open
jbkjr wants to merge 2 commits intoai-zerolab:mainfrom
Open
Fix: _batch_fetch_headers UID parsing for aioimaplib response format#111jbkjr wants to merge 2 commits intoai-zerolab:mainfrom
jbkjr wants to merge 2 commits intoai-zerolab:mainfrom
Conversation
aioimaplib returns FETCH responses in 3 separate parts:
- i: b'N FETCH (BODY[HEADER] {size}' - contains BODY[HEADER]
- i+1: bytearray(...) - raw header content
- i+2: b' UID N)' - contains UID
The original code assumed UID was on the same line as BODY[HEADER], but
aioimaplib separates them. This caused list_emails_metadata to return
empty results when used with actual IMAP servers.
Also fixes test mocks to use correct response format.
Fixes batch fetch regression introduced in PR ai-zerolab#107.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Add tests covering all edge cases in the UID parsing logic: - Skips non-bytes items in response data - Skips items without BODY[HEADER] marker - Handles truncated responses (missing UID line) - Handles non-bytearray content - Handles non-bytes UID item - Handles missing UID in response line - Handles mixed valid/invalid items in same response These tests ensure robustness of the aioimaplib response parsing fix. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
jbkjr
pushed a commit
to jbkjr/mcp-email-server
that referenced
this pull request
Jan 26, 2026
Sync local-dev with PR ai-zerolab#111 tests covering all edge cases: - Skips non-bytes items in response - Skips items without BODY[HEADER] marker - Handles truncated responses - Handles non-bytearray content - Handles non-bytes UID item - Handles missing UID in response - Handles mixed valid/invalid items Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
_batch_fetch_headersintroduced in PR Perf: Batch fetch emails to reduce IMAP round trips #107 where aioimaplib response format was incorrectly assumedProblem
PR #107 ("Batch fetch emails to reduce IMAP round trips") introduced a regression in
_batch_fetch_headers. The function fails to parse email metadata because it assumes the UID appears on the same line asBODY[HEADER], but aioimaplib returns them separately.Actual aioimaplib response format:
[ b'2 FETCH (BODY[HEADER] {6149}', # Item i: has BODY[HEADER], NO UID bytearray(b'From: ...headers...'), # Item i+1: header content b' UID 47)', # Item i+2: UID here! ]What the code expected (and tests mocked):
[ b'1 FETCH (UID 100 BODY[HEADER] {50}', # UID on same line - WRONG bytearray(b'From: ...'), b')', ]Fix
Updated
_batch_fetch_headersto look for UID indata[i + 2]instead ofdata[i], matching the actual aioimaplib response format.Test plan
uv run pytest tests/test_email_client.py tests/test_classic_handler.py -v(43 passed)🤖 Generated with Claude Code