{"record":{"id":"4088294d3c8ea595","repo":"larksuite/cli","slug":"draft-has-no-primary-s-body-part","errorCode":null,"errorMessage":"draft has no primary %s body part","messagePattern":"draft has no primary (.+?) body part","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/draft/patch.go","lineNumber":422,"sourceCode":"\tif bodyLooksLikeHTML(value) {\n\t\treturn nil\n\t}\n\treturn fmt.Errorf(\"draft main body is text/html and text/plain is only its summary; set_body requires HTML input for this draft\")\n}\n\nfunc bodyPartForKind(snapshot *DraftSnapshot, bodyKind string, allowRewrite bool) (*Part, error) {\n\tvar partID string\n\tswitch strings.ToLower(bodyKind) {\n\tcase \"text/plain\":\n\t\tpartID = snapshot.PrimaryTextPartID\n\tcase \"text/html\":\n\t\tpartID = snapshot.PrimaryHTMLPartID\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported body kind %q\", bodyKind)\n\t}\n\tif partID == \"\" {\n\t\tif !allowRewrite {\n\t\t\treturn nil, fmt.Errorf(\"draft has no primary %s body part\", bodyKind)\n\t\t}\n\t\treturn ensureBodyPart(snapshot, bodyKind)\n\t}\n\tpart := findPart(snapshot.Body, partID)\n\tif part == nil {\n\t\treturn nil, fmt.Errorf(\"body part %s not found\", partID)\n\t}\n\treturn part, nil\n}\n\nfunc ensureBodyPart(snapshot *DraftSnapshot, bodyKind string) (*Part, error) {\n\tpartRef := primaryBodyRootRef(&snapshot.Body)\n\tif partRef == nil {\n\t\treturn nil, fmt.Errorf(\"draft has no primary body container\")\n\t}\n\treturn ensureBodyPartRef(partRef, bodyKind)\n}\n","sourceCodeStart":404,"sourceCodeEnd":440,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/draft/patch.go#L404-L440","documentation":"This error means the draft's MIME snapshot has no primary body part of the requested kind (text/plain or text/html): PrimaryTextPartID or PrimaryHTMLPartID is empty. bodyPartForKind only auto-creates a missing body when allowRewrite is true (e.g. rewrite_entire_draft); plain replaceBody/appendBody operations require an existing primary part and refuse to synthesize one. It protects drafts whose structure doesn't include that body variant from being silently restructured by a targeted body patch.","triggerScenarios":"Calling replaceBody or appendBody (via draft patch body operations like set_body/append_body) on a draft whose snapshot lacks a primary part for the requested bodyKind — e.g. patching text/plain on an HTML-only draft, or patching text/html on a plain-text-only draft.","commonSituations":"Patching a draft created with only one body representation; drafts fetched from the API where one MIME leaf is absent; automation scripts that assume every draft has both text and HTML bodies; using set_body on an attachment-only or unusual MIME structure.","solutions":["Check which body kind the draft actually has before patching (inspect the draft's MIME structure / primary part IDs) and request the matching kind.","Use the rewrite_entire_draft path (allowRewrite=true) instead of set_body/append_body when the missing body kind should be synthesized.","Convert the draft's body to the desired structure first (e.g. set the body once via rewrite) so the primary part exists, then apply targeted patches."],"exampleFix":"// before: patching text/plain on an HTML-only draft\nerr := replaceBody(ctx, snapshot, \"text/plain\", body)\n// after: rewrite so the missing primary part is created\nerr := replaceBodyAllowRewrite(ctx, snapshot, \"text/plain\", body) // allowRewrite=true","handlingStrategy":"validation","validationCode":"func canPatchBody(s *DraftSnapshot, kind string) bool {\n\tid := s.PrimaryTextPartID\n\tif kind == \"text/html\" {\n\t\tid = s.PrimaryHTMLPartID\n\t}\n\treturn id != \"\" && findPart(s.Body, id) != nil\n}\nif !canPatchBody(snapshot, \"text/plain\") { /* use rewrite path */ }","typeGuard":"func hasPrimaryBody(s *DraftSnapshot, kind string) bool {\n\tid := s.PrimaryTextPartID\n\tif strings.EqualFold(kind, \"text/html\") { id = s.PrimaryHTMLPartID }\n\treturn id != \"\" && findPart(s.Body, id) != nil\n}","tryCatchPattern":null,"preventionTips":["Inspect the draft's MIME structure before choosing which body kind to patch.","Prefer the rewrite (allowRewrite) path when the draft may lack one body representation.","Never assume both text/plain and text/html exist; single-representation drafts are common."],"tags":["email","mime","draft","validation"],"backgroundTag":"draft-body-part-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"}