larksuite/cli · error

cannot rewrite non-body media type %q

Error message

cannot rewrite non-body media type %q

What it means

The draft's primary body slot holds a non-multipart part whose media type is neither text/plain, text/html, nor equal to the requested bodyKind (isBodyKind fails). The library cannot safely convert such content (e.g. application/pdf, image/*, text/calendar) into a text body, so it refuses the rewrite rather than destroying the existing part. This protects drafts whose primary content is not rewriteable text.

Source

Thrown at shortcuts/mail/draft/patch.go:478

}

func ensureBodyPartRef(partRef **Part, bodyKind string) (*Part, error) {
	if partRef == nil {
		return nil, fmt.Errorf("body container is nil")
	}
	if *partRef == nil {
		leaf := newBodyLeaf(bodyKind)
		leaf.Dirty = true
		*partRef = leaf
		return leaf, nil
	}
	part := *partRef
	if !part.IsMultipart() {
		if strings.EqualFold(part.MediaType, bodyKind) {
			return part, nil
		}
		if !isBodyKind(part.MediaType) {
			return nil, fmt.Errorf("cannot rewrite non-body media type %q", part.MediaType)
		}
		newLeaf := newBodyLeaf(bodyKind)
		alt := newMultipartContainer("multipart/alternative")
		if strings.EqualFold(part.MediaType, "text/plain") {
			alt.Children = []*Part{part, newLeaf}
		} else {
			alt.Children = []*Part{newLeaf, part}
		}
		alt.Dirty = true
		newLeaf.Dirty = true
		*partRef = alt
		return newLeaf, nil
	}

	switch strings.ToLower(part.MediaType) {
	case "multipart/alternative":
		for _, child := range part.Children {
			if child != nil && strings.EqualFold(child.MediaType, bodyKind) {

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Inspect snapshot.Body.MediaType before rewriting and wrap non-body roots into a multipart/mixed container (with the real content as one child and the body as another) using the attachment path.
  2. Add the attachment via addAttachment instead of placing it as the root body, so the root stays a body kind and rewrite works.
  3. Rebuild the draft with a proper body structure if the source system produced a non-body root.

Example fix

// before: attachment stored as root body
snapshot.Body = pdfPart
err := ensureBodyPart(snapshot, "text/html") // fails
// after: proper structure
snapshot.Body = textLeaf
addAttachment(ctx, snapshot, "report.pdf")
err := ensureBodyPart(snapshot, "text/html")
Defensive patterns

Strategy: validation

Validate before calling

if snapshot.Body != nil && !snapshot.Body.IsMultipart() && !isBodyKind(snapshot.Body.MediaType) {
	// root is non-body content: restructure or use attachment flow first
	addAttachment(ctx, snapshot, filePath)
	snapshot.Body = newBodyLeaf("text/plain")
}

Type guard

func bodyRewritable(p *Part) bool {
	return p != nil && (p.IsMultipart() || isBodyKind(p.MediaType))
}

Prevention

When it happens

Trigger: Rewriting the body of a draft whose root body part has a non-body media type — e.g. a draft consisting of a single attachment-like part (application/octet-stream, image/png) or a non-MIME content type — then calling a body rewrite targeting text/plain or text/html.

Common situations: Drafts imported from external systems with odd root MIME structures; snapshots where the body slot was overwritten with attachment content; automation that assumes the root is always text or multipart.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/8d92c35e1c3e3c46. Report an issue: GitHub.