-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Description
gws gmail +reply-all silently drops CC recipients when the original message's Cc header is stored with non-canonical casing (e.g., "CC" instead of "Cc").
Reproduction
- Have a Gmail thread where the latest message has CC recipients and the header name is
"CC"(all uppercase — common with Microsoft Exchange / Outlook) - Run:
gws gmail +reply-all --message-id <ID> --body 'test' --draft
- Expected: Draft includes all original To + CC recipients
- Actual: Draft only includes To recipients + original sender. All CC recipients are silently dropped.
Root Cause
parse_message_headers in crates/google-workspace-cli/src/helpers/gmail/mod.rs (line 254) uses exact case-sensitive string matching:
match name {
"From" => ...
"Reply-To" => ...
"To" => ...
"Cc" => ... // ← only matches "Cc"
"Message-ID" | "Message-Id" => ... // ← already handles 2 variants
_ => {} // ← "CC" falls through silently
}The Gmail API preserves original header casing from the sending MTA. Per RFC 5322 §1.2.2, header field names are case-insensitive, so "CC", "Cc", and "cc" are all valid.
Scope
This affects all headers in the match block, not just Cc. If any header arrives in non-canonical casing:
| Header | Impact if missed |
|---|---|
From |
Hard error — function returns Err("Message is missing From header") |
Message-ID |
Hard error — Err("Message is missing Message-ID header") |
To |
+reply-all misses To recipients |
CC |
+reply-all drops CC recipients (this bug) |
Reply-To |
Reply goes to wrong recipient |
References |
Threading breaks |
Internal Inconsistency
The same file already uses case-insensitive matching in get_part_header:
fn get_part_header<'a>(part: &'a Value, name: &str) -> Option<&'a str> {
...
.find(|h| n.eq_ignore_ascii_case(name)) // ← correct approach
...
}Suggested Fix
Normalize name before matching:
match name.to_ascii_lowercase().as_str() {
"from" => ...
"reply-to" => ...
"to" => ...
"cc" => ...
"subject" => ...
"date" => ...
"message-id" => ...
"references" => ...
_ => {}
}This aligns with the existing get_part_header pattern and the extract_header function (which also uses eq_ignore_ascii_case).
Related
- Cc and Bcc headers placed after Content-Type — recipients don't receive emails #569 — CC header ordering issue (different bug, fixed)
- PR feat(gmail): add +reply, +reply-all, and +forward helpers #105 — Original
+reply-allimplementation - PR feat(gmail): replace +triage with +search for full-metadata Gmail search #634 (open) — Widens
parse_message_headerstopub(super)for reuse; this bug would propagate
Environment
- gws 0.22.3
- macOS (arm64)
- Original message sent from Microsoft Exchange (which emits
"CC"in uppercase)