{"record":{"id":"a321b7de0c7562fc","repo":"larksuite/cli","slug":"unsupported-body-kind-q","errorCode":null,"errorMessage":"unsupported body kind %q","messagePattern":"unsupported body kind %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/draft/patch.go","lineNumber":418,"sourceCode":"func coupledBodySetBodyInputError(snapshot *DraftSnapshot, value string) error {\n\tif !hasCoupledBodySummary(snapshot) {\n\t\treturn nil\n\t}\n\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\")","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/draft/patch.go#L400-L436","documentation":"bodyPartForKind maps a body_kind string to the corresponding primary part ID. Only 'text/plain' and 'text/html' are recognized; any other value (including typos like 'text/html;' or 'plain') is rejected with this error before any part lookup.","triggerScenarios":"A replace_body or append_body patch op (via applyOp) with body_kind not exactly 'text/plain' or 'text/html' (case-insensitive) — e.g. 'html', 'text', 'text/calendar', or a value with trailing whitespace characters.","commonSituations":"Typos or abbreviated kind names in scripts; passing a MIME type from elsewhere (e.g. attachment content types like application/pdf); config values copied from another tool's API.","solutions":["Use exactly 'text/plain' or 'text/html' as body_kind","Normalize/validate the kind string against the allowed set before building the op","If the kind comes from user input, map unsupported values explicitly instead of passing them through"],"exampleFix":"// before\napplyOp(Op{Op: \"replace_body\", BodyKind: \"html\", Value: html})\n// after\napplyOp(Op{Op: \"replace_body\", BodyKind: \"text/html\", Value: html})","handlingStrategy":"validation","validationCode":"var validBodyKinds = map[string]bool{\"text/plain\": true, \"text/html\": true}\nif !validBodyKinds[strings.ToLower(strings.TrimSpace(kind))] {\n    return fmt.Errorf(\"body_kind must be text/plain or text/html\")\n}","typeGuard":"func isBodyKind(s string) bool {\n    switch strings.ToLower(strings.TrimSpace(s)) {\n    case \"text/plain\", \"text/html\":\n        return true\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Only pass the literal values 'text/plain' or 'text/html' as body_kind","Normalize user/config-provided kind strings against the allowed set","Keep MIME attachment types (application/pdf, etc.) out of body_kind"],"tags":["validation","draft-patch","email"],"backgroundTag":"invalid-enum-value","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"}