larksuite/cli · error
draft has no MIME body
Error message
draft has no MIME body
What it means
removeAttachment throws this when the draft snapshot has no MIME body at all (snapshot.Body is nil), so there is no attachment tree to search. A draft without MIME parts cannot have attachments removed.
Source
Thrown at shortcuts/mail/draft/patch.go:752
part := findPart(snapshot.Body, partID)
if part == nil {
return fmt.Errorf("inline part %q not found", partID)
}
if !isInlinePart(part) {
return fmt.Errorf("part %q is not an inline MIME part", partID)
}
if snapshot.Body == nil || snapshot.Body.PartID == partID {
return fmt.Errorf("cannot remove root MIME part")
}
if !removePart(snapshot.Body, partID) {
return fmt.Errorf("inline part %q not found", partID)
}
return nil
}
func removeAttachment(snapshot *DraftSnapshot, partID string) error {
if snapshot.Body == nil {
return fmt.Errorf("draft has no MIME body")
}
part := findPart(snapshot.Body, partID)
if part == nil {
return fmt.Errorf("attachment part %q not found", partID)
}
if strings.EqualFold(part.ContentDisposition, "inline") || part.ContentID != "" {
return fmt.Errorf("part %q is an inline MIME part; use remove_inline", partID)
}
if snapshot.Body.PartID == partID {
return fmt.Errorf("cannot remove root MIME part")
}
removed := removePart(snapshot.Body, partID)
if !removed {
return fmt.Errorf("attachment part %q not found", partID)
}
return nil
}
View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Confirm with a fresh draft get that the draft actually has MIME parts
- Add content/attachments first; you cannot remove from an empty body
- Skip the removal if the draft has no attachments (nothing to do)
- If the draft should have parts, recreate it with the intended body and attachments
Example fix
// before lark mail draft patch --draft-id D --remove-attachment part_id=a_1 # empty draft // after lark mail draft get --draft-id D # verify attachments exist first lark mail draft patch --draft-id D --remove-attachment part_id=<existing>
Defensive patterns
Strategy: validation
Validate before calling
snap, _ := draftGet(draftID)
if snap.Body == nil {
return errors.New("draft has no MIME body; nothing to remove")
} Type guard
func hasBody(snap *DraftSnapshot) bool { return snap != nil && snap.Body != nil } Try / catch
if err := removeAttachment(...); err != nil {
if strings.Contains(err.Error(), "no MIME body") {
return nil // nothing to remove
}
return err
} Prevention
- Verify the draft has MIME parts before attachment operations
- Skip removal ops on empty/plain-text drafts
- Fetch a fresh snapshot before patching
- Create drafts with bodies when attachment management is planned
When it happens
Trigger: applyOp -> removeAttachment on a draft whose body was never initialized as MIME (empty draft, plain-text draft, or snapshot taken before any part was added).
Common situations: Removing attachments from a freshly created empty draft; draft downgraded to plain text; operating on a snapshot fetched before body creation.
Related errors
- add_attachment requires path
- remove_attachment requires target with at least one of part_
- add_inline requires path
- add_inline requires cid
- replace_inline requires target with at least one of part_id
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/64f54e7bc8ac19e5.
Report an issue: GitHub.