larksuite/cli · error

draft snapshot is empty

Error message

draft snapshot is empty

What it means

Serialize renders a DraftSnapshot back into an RFC 2822 MIME string. It requires a non-nil snapshot with a non-nil Body; anything else cannot be serialized, so it fails immediately with this error before writing any output. It guards against serializing half-constructed or reset snapshots.

Source

Thrown at shortcuts/mail/draft/serialize.go:19

// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT

//nolint:forbidigo // intermediate draft serializer errors; mail command layer wraps into typed ValidationError.
package draft

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"math/rand"
	"mime"
	"mime/quotedprintable"
	"strings"
)

func Serialize(snapshot *DraftSnapshot) (string, error) {
	if snapshot == nil || snapshot.Body == nil {
		return "", fmt.Errorf("draft snapshot is empty")
	}
	var buf bytes.Buffer
	mimeVersionValue := "1.0"
	wroteMimeVersion := false
	for _, header := range snapshot.Headers {
		if strings.EqualFold(header.Name, "MIME-Version") {
			mimeVersionValue = header.Value
			writeHeader(&buf, header.Name, header.Value)
			wroteMimeVersion = true
			continue
		}
		if isBodyHeader(header.Name) {
			continue
		}
		writeHeader(&buf, header.Name, header.Value)
	}
	if !wroteMimeVersion {
		writeHeader(&buf, "MIME-Version", mimeVersionValue)

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Ensure the snapshot was produced by a successful Deserialize/set_body before serializing
  2. Check that snapshot.Body is non-nil before calling Serialize
  3. Fix the earlier load/build failure that left the snapshot empty instead of serializing anyway

Example fix

// before
out, err := draft.Serialize(snap) // snap.Body == nil
// after
if snap == nil || snap.Body == nil { return fmt.Errorf("draft not loaded") }
out, err := draft.Serialize(snap)
Defensive patterns

Strategy: type-guard

Type guard

func serializable(s *DraftSnapshot) bool { return s != nil && s.Body != nil }

Try / catch

out, err := draft.Serialize(snap)
if err != nil {
  if strings.Contains(err.Error(), "draft snapshot is empty") {
    return reloadDraft() // rebuild snapshot from source before saving
  }
  return err
}

Prevention

When it happens

Trigger: Calling Serialize (directly or via draft save flows, as in the acceptance tests) with a nil *DraftSnapshot or a snapshot whose Body field was never initialized.

Common situations: Zero-value DraftSnapshot returned by a failed load; a snapshot reset/cleared between deserialize and serialize; forgetting to run the parse/build step before saving.

Related errors


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