larksuite/cli · error

set_calendar: ICS data is empty (shortcut layer must pre-bui

Error message

set_calendar: ICS data is empty (shortcut layer must pre-build it)

What it means

applyCalendarSet installs the text/calendar MIME part from pre-built ICS bytes, but it deliberately does not build ICS itself — the shortcut layer must construct icsData from the snapshot's From/To/Cc addresses. An empty icsData means the caller broke that contract, so it fails with this internal-guard error naming the responsible layer.

Source

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

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

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

import (
	"fmt"
	"strings"
)

const calendarMediaType = "text/calendar"

// applyCalendarSet installs or replaces the text/calendar MIME part in the
// snapshot. The caller is expected to have pre-built icsData using the
// snapshot's From/To/Cc addresses.
func applyCalendarSet(snapshot *DraftSnapshot, icsData []byte) error {
	if len(icsData) == 0 {
		return fmt.Errorf("set_calendar: ICS data is empty (shortcut layer must pre-build it)")
	}
	setCalendarPart(snapshot, icsData)
	return nil
}

// applyCalendarRemove strips the text/calendar part from the snapshot.
// No-op if no calendar part exists.
func applyCalendarRemove(snapshot *DraftSnapshot) error {
	removeCalendarPart(snapshot)
	return nil
}

// setCalendarPart places exactly one text/calendar part inside
// multipart/alternative, matching the Feishu client behavior. Any existing
// text/calendar parts elsewhere in the tree are removed first.
func setCalendarPart(snapshot *DraftSnapshot, icsData []byte) {
	newPart := &Part{
		MediaType:   calendarMediaType,

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Pre-build the ICS payload from snapshot.From/To/Cc before invoking set_calendar
  2. Skip the set_calendar op when there is genuinely no calendar content
  3. Add a guard in the shortcut layer that refuses set_calendar when ICS generation yields zero bytes

Example fix

// before
applyOp(snapshot, PatchOp{Type: "set_calendar", ICS: ics}) // ics empty
// after
ics, err := buildICS(snapshot) // must produce non-empty ICS
if err != nil || len(ics) == 0 { return err }
applyOp(snapshot, PatchOp{Type: "set_calendar", ICS: ics})
Defensive patterns

Strategy: validation

Validate before calling

if len(icsData) == 0 {
  return fmt.Errorf("refusing set_calendar: ICS not built")
}
applyOp(snapshot, PatchOp{Type: "set_calendar", ICS: icsData})

Type guard

func hasCalendarData(op PatchOp) bool { return len(op.ICS) > 0 }

Try / catch

err := applyOp(snapshot, op)
if err != nil && strings.Contains(err.Error(), "ICS data is empty") {
  return fmt.Errorf("shortcut layer must build ICS before set_calendar: %w", err)
}

Prevention

When it happens

Trigger: Applying a set_calendar op where the shortcut layer passed nil/empty ICS bytes — e.g. calendar event data could not be generated, attendees were empty, or the pre-build step was skipped in a new code path.

Common situations: New shortcut wiring that calls applyOp with set_calendar before running the ICS builder; an upstream calendar-data fetch returning nothing; refactors that changed where icsData is produced.

Related errors


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