{"record":{"id":"64f54e7bc8ac19e5","repo":"larksuite/cli","slug":"draft-has-no-mime-body","errorCode":null,"errorMessage":"draft has no MIME body","messagePattern":"draft has no MIME body","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/draft/patch.go","lineNumber":752,"sourceCode":"\tpart := findPart(snapshot.Body, partID)\n\tif part == nil {\n\t\treturn fmt.Errorf(\"inline part %q not found\", partID)\n\t}\n\tif !isInlinePart(part) {\n\t\treturn fmt.Errorf(\"part %q is not an inline MIME part\", partID)\n\t}\n\tif snapshot.Body == nil || snapshot.Body.PartID == partID {\n\t\treturn fmt.Errorf(\"cannot remove root MIME part\")\n\t}\n\tif !removePart(snapshot.Body, partID) {\n\t\treturn fmt.Errorf(\"inline part %q not found\", partID)\n\t}\n\treturn nil\n}\n\nfunc removeAttachment(snapshot *DraftSnapshot, partID string) error {\n\tif snapshot.Body == nil {\n\t\treturn fmt.Errorf(\"draft has no MIME body\")\n\t}\n\tpart := findPart(snapshot.Body, partID)\n\tif part == nil {\n\t\treturn fmt.Errorf(\"attachment part %q not found\", partID)\n\t}\n\tif strings.EqualFold(part.ContentDisposition, \"inline\") || part.ContentID != \"\" {\n\t\treturn fmt.Errorf(\"part %q is an inline MIME part; use remove_inline\", partID)\n\t}\n\tif snapshot.Body.PartID == partID {\n\t\treturn fmt.Errorf(\"cannot remove root MIME part\")\n\t}\n\tremoved := removePart(snapshot.Body, partID)\n\tif !removed {\n\t\treturn fmt.Errorf(\"attachment part %q not found\", partID)\n\t}\n\treturn nil\n}\n","sourceCodeStart":734,"sourceCodeEnd":770,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/draft/patch.go#L734-L770","documentation":"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.","triggerScenarios":"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).","commonSituations":"Removing attachments from a freshly created empty draft; draft downgraded to plain text; operating on a snapshot fetched before body creation.","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"],"exampleFix":"// before\nlark mail draft patch --draft-id D --remove-attachment part_id=a_1   # empty draft\n// after\nlark mail draft get --draft-id D   # verify attachments exist first\nlark mail draft patch --draft-id D --remove-attachment part_id=<existing>","handlingStrategy":"validation","validationCode":"snap, _ := draftGet(draftID)\nif snap.Body == nil {\n    return errors.New(\"draft has no MIME body; nothing to remove\")\n}","typeGuard":"func hasBody(snap *DraftSnapshot) bool { return snap != nil && snap.Body != nil }","tryCatchPattern":"if err := removeAttachment(...); err != nil {\n    if strings.Contains(err.Error(), \"no MIME body\") {\n        return nil // nothing to remove\n    }\n    return err\n}","preventionTips":["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"],"tags":["mail","draft","attachment","no-body"],"backgroundTag":"draft-body-container-missing","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}