{"record":{"id":"7ba101a632ae508e","repo":"larksuite/cli","slug":"set-calendar-ics-data-is-empty-shortcut-layer-mu","errorCode":null,"errorMessage":"set_calendar: ICS data is empty (shortcut layer must pre-build it)","messagePattern":"set_calendar: ICS data is empty \\(shortcut layer must pre-build it\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/draft/patch_calendar.go","lineNumber":19,"sourceCode":"// Copyright (c) 2026 Lark Technologies Pte. Ltd.\n// SPDX-License-Identifier: MIT\n\n//nolint:forbidigo // intermediate draft calendar patch errors; mail command layer wraps into typed ValidationError.\npackage draft\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nconst calendarMediaType = \"text/calendar\"\n\n// applyCalendarSet installs or replaces the text/calendar MIME part in the\n// snapshot. The caller is expected to have pre-built icsData using the\n// snapshot's From/To/Cc addresses.\nfunc applyCalendarSet(snapshot *DraftSnapshot, icsData []byte) error {\n\tif len(icsData) == 0 {\n\t\treturn fmt.Errorf(\"set_calendar: ICS data is empty (shortcut layer must pre-build it)\")\n\t}\n\tsetCalendarPart(snapshot, icsData)\n\treturn nil\n}\n\n// applyCalendarRemove strips the text/calendar part from the snapshot.\n// No-op if no calendar part exists.\nfunc applyCalendarRemove(snapshot *DraftSnapshot) error {\n\tremoveCalendarPart(snapshot)\n\treturn nil\n}\n\n// setCalendarPart places exactly one text/calendar part inside\n// multipart/alternative, matching the Feishu client behavior. Any existing\n// text/calendar parts elsewhere in the tree are removed first.\nfunc setCalendarPart(snapshot *DraftSnapshot, icsData []byte) {\n\tnewPart := &Part{\n\t\tMediaType:   calendarMediaType,","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/draft/patch_calendar.go#L1-L37","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pre-build the ICS payload from snapshot.From/To/Cc before invoking set_calendar","Skip the set_calendar op when there is genuinely no calendar content","Add a guard in the shortcut layer that refuses set_calendar when ICS generation yields zero bytes"],"exampleFix":"// before\napplyOp(snapshot, PatchOp{Type: \"set_calendar\", ICS: ics}) // ics empty\n// after\nics, err := buildICS(snapshot) // must produce non-empty ICS\nif err != nil || len(ics) == 0 { return err }\napplyOp(snapshot, PatchOp{Type: \"set_calendar\", ICS: ics})","handlingStrategy":"validation","validationCode":"if len(icsData) == 0 {\n  return fmt.Errorf(\"refusing set_calendar: ICS not built\")\n}\napplyOp(snapshot, PatchOp{Type: \"set_calendar\", ICS: icsData})","typeGuard":"func hasCalendarData(op PatchOp) bool { return len(op.ICS) > 0 }","tryCatchPattern":"err := applyOp(snapshot, op)\nif err != nil && strings.Contains(err.Error(), \"ICS data is empty\") {\n  return fmt.Errorf(\"shortcut layer must build ICS before set_calendar: %w\", err)\n}","preventionTips":["Build ICS from snapshot From/To/Cc before every set_calendar call","Skip set_calendar when no event data exists","Keep ICS generation in the shortcut layer, never assume the patch op builds it"],"tags":["mail","calendar","ics","internal-contract"],"backgroundTag":"empty-calendar-invite-data","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}