larksuite/cli · error
insert_signature: no HTML body part found; use set_body firs
Error message
insert_signature: no HTML body part found; use set_body first
What it means
insertSignatureOp needs an HTML body part in the draft snapshot to splice the signature markup into. If findPart cannot locate the primary HTML part (no multipart/alternative HTML node exists), there is nothing to insert into, so it fails with this directive-style error telling the caller to create a body first. The signature machinery never fabricates an HTML part by itself.
Source
Thrown at shortcuts/mail/draft/patch.go:1227
}
removeOrphanedInlineParts(snapshot.Body, refSet)
return nil
}
// ── Signature patch operations ──
// insertSignatureOp inserts a pre-rendered signature into the HTML body.
// The RenderedSignatureHTML and SignatureImages fields must be populated
// by the shortcut layer before calling Apply.
//
// Placement: signature goes between the user-authored region and any
// system-managed tail (large attachment card or history quote wrapper),
// matching the compose-time order [user][sig][card?][quote?]. When the
// draft already has a signature, it is replaced in place.
func insertSignatureOp(snapshot *DraftSnapshot, op PatchOp) error {
htmlPart := findPart(snapshot.Body, snapshot.PrimaryHTMLPartID)
if htmlPart == nil {
return fmt.Errorf("insert_signature: no HTML body part found; use set_body first")
}
oldHTML := string(htmlPart.Body)
// Collect CIDs from old signature before replacement so we can prune
// MIME inline parts that the new signature doesn't re-reference.
oldSigCIDs := collectSignatureCIDsFromHTML(oldHTML)
sigBlock := SignatureSpacing() + BuildSignatureHTML(op.SignatureID, op.RenderedSignatureHTML)
newHTML := PlaceSignatureBeforeSystemTail(oldHTML, sigBlock)
// Remove orphaned MIME inline parts from old signature.
for _, cid := range oldSigCIDs {
if !containsCIDIgnoreCase(newHTML, cid) {
removeMIMEPartByCID(snapshot.Body, cid)
}
}
htmlPart.Body = []byte(newHTML)View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Call set_body first so the snapshot gains an HTML body part, then re-run insert_signature
- Verify PrimaryHTMLPartID points to the intended HTML part (leave empty only when exactly one HTML part exists)
- Inspect the snapshot's parts to confirm a text/html part exists before applying signature ops
Example fix
// before
applyOp(snapshot, PatchOp{Type: "insert_signature"}) // fails: no HTML part
// after
setBody(snapshot, "<html><body>Hello</body></html>") // establishes HTML part
applyOp(snapshot, PatchOp{Type: "insert_signature"}) Defensive patterns
Strategy: validation
Validate before calling
if findPart(snapshot.Body, snapshot.PrimaryHTMLPartID) == nil {
return fmt.Errorf("draft has no HTML body; call set_body before insert_signature")
} Type guard
func hasHTMLPart(s *DraftSnapshot) bool {
return s != nil && findPart(s.Body, s.PrimaryHTMLPartID) != nil
} Try / catch
err := applyOp(snapshot, op)
if err != nil && strings.Contains(err.Error(), "no HTML body part found") {
return fmt.Errorf("create the draft body first: %w", err)
} Prevention
- Always run set_body before signature ops
- Check the draft has a text/html part for HTML signatures
- Keep the op order fixed: set_body → insert_signature → other ops
- Assert snapshot invariants in your pipeline before applying ops
When it happens
Trigger: Applying an insert_signature patch op to a snapshot whose Body has no HTML part and whose PrimaryHTMLPartID is empty/unresolvable — typically a plain-text-only draft, or a draft built without a prior set_body that established the HTML part.
Common situations: Composing a plain-text mail draft and then trying to add a signature; running signature ops in the wrong order on a freshly created draft; migrating drafts where the HTML alternative part was stripped.
Related errors
- remove_signature: no HTML body part found
- no signature found in draft body
- %s header is empty
- html body references missing inline cid %q
- draft snapshot is empty
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/82800c1c051bb595.
Report an issue: GitHub.