Repository navigation
Description
Found while building a personal mail-triage workflow on top of this library (rule authoring + a read-only mailbox scan). Each item below is a confirmed, reproduced gap — not speculative — that has a workaround in place today but would directly unblock or improve a downstream feature if fixed upstream.
1. rule-create cannot target nested folders
_resolve_folder_id (src/msgraph/graph.py:12) does a shallow GET /me/mailFolders (top-level only), so --move_to_folder naming a folder nested under Inbox/Archive fails with "No mail folder named …", and doesn't accept a folder id either. message-move's _resolve_destination_folder (graph.py:46) already recurses to any depth and accepts an opaque id — the two verbs are inconsistent.
Impact: blocks authoring a move-to-folder rule targeting any nested destination folder.
Fix: point rule-create's destination resolution at _resolve_destination_folder (or the recursive _folder_name_map) so rules can file into nested folders and accept ids, matching message-move.
2. rule-create hardcodes stopProcessingRules and sequence
The POST body hardcodes "stopProcessingRules": False and "sequence": 1 (src/msgraph/verbs.py ~line 240) — callers have no control over rule order or chain-stop. With overlapping predicates, the last matching rule's move silently wins over earlier, more specific rules.
Impact: forces a workaround of only ever authoring non-overlapping predicates to sidestep ordering entirely; makes it impossible to express "specific rule wins, then fall through to a broader catch-all."
Fix: expose stopProcessingRules and sequence as rule-create arguments so specific-before-broad ordering is enforceable.
3. mail-list exposes no isRead or categories field
Even in --format detailed, mail-list returns only a minimal projection (from, id, receivedDateTime, subject). Per-message read status and category tags are not obtainable from any read-only verb.
Impact: blocks any read-only client from enumerating which category-tagged items are unread — can only degrade to folder-level unread counts. Reproduced live 2026-07-23 (mail-list --folder <name> --format detailed on 500 messages returned zero usable categories/isRead fields to filter on).
Fix: add isRead and categories to the $select (and JSON output) for mail-list --format detailed.
4. searchfolder-create's documented --source_folders default doesn't appear to apply
Docs state --source_folders defaults to inbox, but a search folder created via this verb (omitting --source_folders) reports "shallow over 0 source folder(s)" when inspected via searchfolder-list --format detailed — meaning its filter can structurally never match anything, regardless of how much matching mail exists.
Impact: a category-filtered search folder created without an explicit --source_folders silently returns nothing forever. Discovered live 2026-07-23.
Fix: confirm whether the default is actually applied at creation time (vs. only documented), and either fix the default or make the omission fail loudly instead of creating a folder that can never match.
None of these are blocking outright — each has a workaround in place — but fixing them removes real workaround debt for anyone building rule-authoring or read-only scanning tools on top of this library.
Activity
[-]Close the four confirmed kypr-blocking gaps in msgraph-stdlib[/-][+]Close four confirmed downstream-blocking gaps[/+]neilgfoster commentedon Jul 23, 2026
Epic-scoped finding from #18: child #18 (nested-folder rule-create fix) was a stale duplicate — the fix already landed on
mainvia PR #14 before this epic was decomposed. Closed #18 without a new PR. Worth checking during any future re-decompose pass whether other epic-body items similarly predate already-shipped fixes.Expose --sequence and --stop_processing_rules on rule-create so calle…
neilgfoster commentedon Jul 24, 2026
All 4 items resolved: nested-folder rule-create fix predated this epic (PR #14); rule ordering (#19 → PR #24), mail-list isRead/categories (#20 → PR #22), and searchfolder-create source-folder default (#21 → PR #23) all shipped via merged PRs. Re-decompose check found no further gaps. Closing.
release: 0.7.0 (#25)