larksuite/cli · error
rewrite_entire_draft cannot synthesize body inside %q
Error message
rewrite_entire_draft cannot synthesize body inside %q
What it means
During body synthesis, the recursive ensureBodyPartRef walked into a multipart container it does not understand (anything other than multipart/alternative or multipart/related, e.g. multipart/mixed as a body child or multipart/digest, multipart/signed). The rewrite_entire_draft path only knows how to synthesize a text body inside alternative/related containers, so it fails explicitly with the offending media type.
Source
Thrown at shortcuts/mail/draft/patch.go:528
for idx := range part.Children {
child := part.Children[idx]
if child == nil {
continue
}
if child.IsMultipart() && strings.EqualFold(child.MediaType, "multipart/alternative") {
return ensureBodyPartRef(&part.Children[idx], bodyKind)
}
}
if len(part.Children) == 0 {
leaf := newBodyLeaf(bodyKind)
part.Children = append(part.Children, leaf)
part.Dirty = true
leaf.Dirty = true
return leaf, nil
}
return ensureBodyPartRef(&part.Children[0], bodyKind)
default:
return nil, fmt.Errorf("rewrite_entire_draft cannot synthesize body inside %q", part.MediaType)
}
}
func newBodyLeaf(bodyKind string) *Part {
return &Part{
MediaType: strings.ToLower(bodyKind),
MediaParams: map[string]string{"charset": "UTF-8"},
TransferEncoding: "7bit",
Headers: []Header{
{Name: "Content-Type", Value: mime.FormatMediaType(strings.ToLower(bodyKind), map[string]string{"charset": "UTF-8"})},
{Name: "Content-Transfer-Encoding", Value: "7bit"},
},
Body: []byte{},
}
}
func newMultipartContainer(mediaType string) *Part {
boundary := newBoundary()View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Flatten unusual nesting so the body path contains only multipart/alternative and multipart/related before rewriting.
- Rebuild the draft without signed/encrypted wrapping if you need programmatic body rewrite (signing can be reapplied after).
- Handle the offending container manually: locate the text leaf yourself and patch its Body directly instead of using the synthesis path.
Example fix
// before: multipart/related whose child is multipart/mixed related.Children[0] = mixedContainer // after: keep only supported nesting related.Children[0] = altContainer // multipart/alternative
Defensive patterns
Strategy: validation
Validate before calling
func supportedBodyTree(p *Part) bool {
if p == nil { return true }
if p.IsMultipart() {
mt := strings.ToLower(p.MediaType)
if mt != "multipart/alternative" && mt != "multipart/related" && mt != "multipart/mixed" { return false }
for _, c := range p.Children { if !supportedBodyTree(c) { return false } }
}
return true
}
if !supportedBodyTree(snapshot.Body) { /* flatten or rebuild before rewrite */ } Type guard
func synthesizableContainer(p *Part) bool {
mt := strings.ToLower(p.MediaType)
return mt == "multipart/alternative" || mt == "multipart/related"
} Prevention
- Flatten nested multipart/mixed inside related/alternative containers before rewriting.
- Strip multipart/signed or multipart/encrypted wrapping; re-sign after editing.
- Restrict programmatic drafts to alternative/related nesting.
When it happens
Trigger: Rewriting a draft whose body root descends into an unsupported multipart subtype — e.g. primaryBodyRootRef resolves to a multipart/mixed child that is itself multipart/mixed, or the first child of a multipart/related is multipart/signed or multipart/mixed.
Common situations: Drafts produced by other mail clients with nested multipart/mixed inside related containers; signed/encrypted (multipart/signed, multipart/encrypted) drafts; hand-built MIME trees with unusual nesting.
Related errors
- cannot rewrite non-body media type %q
- draft has no primary %s body part
- body part %s not found
- draft has no primary body container
- body container is nil
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/32ecc85a5229951e.
Report an issue: GitHub.