Skip to content

Fix: _batch_fetch_headers UID parsing for aioimaplib response format#111

Open
jbkjr wants to merge 2 commits intoai-zerolab:mainfrom
jbkjr:fix/batch-fetch-headers-uid-parsing
Open

Fix: _batch_fetch_headers UID parsing for aioimaplib response format#111
jbkjr wants to merge 2 commits intoai-zerolab:mainfrom
jbkjr:fix/batch-fetch-headers-uid-parsing

Conversation

@jbkjr
Copy link
Contributor

@jbkjr jbkjr commented Jan 26, 2026

Summary

  • Fixes regression in _batch_fetch_headers introduced in PR Perf: Batch fetch emails to reduce IMAP round trips #107 where aioimaplib response format was incorrectly assumed
  • aioimaplib returns FETCH responses in 3 separate parts, but code expected UID on same line as BODY[HEADER]
  • Updates test mocks to use correct response format

Problem

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 as BODY[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_headers to look for UID in data[i + 2] instead of data[i], matching the actual aioimaplib response format.

Test plan

  • Run existing tests: uv run pytest tests/test_email_client.py tests/test_classic_handler.py -v (43 passed)
  • Test mocks updated to use correct response format

🤖 Generated with Claude Code

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
Copy link

codecov bot commented Jan 26, 2026

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>
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