larksuite/cli · error
set_calendar: event_end must be a valid ISO 8601 timestamp
Error message
set_calendar: event_end must be a valid ISO 8601 timestamp
What it means
Same parse failure as error 840 but for the `event_end` field of a `set_calendar` operation: the value is non-empty yet parseISO8601 cannot match it against any of the four supported layouts (RFC 3339 with/without seconds, with/without timezone offset). The library validates both endpoints up front so a malformed event never reaches the calendar API.
Source
Thrown at shortcuts/mail/draft/model.go:359
if strings.TrimSpace(op.SignatureID) == "" {
return fmt.Errorf("insert_signature requires signature_id")
}
case "remove_signature":
// No required fields.
case "set_calendar":
if strings.TrimSpace(op.EventSummary) == "" {
return fmt.Errorf("set_calendar requires event_summary")
}
if strings.TrimSpace(op.EventStart) == "" || strings.TrimSpace(op.EventEnd) == "" {
return fmt.Errorf("set_calendar requires event_start and event_end")
}
start, err := parseISO8601(op.EventStart)
if err != nil {
return fmt.Errorf("set_calendar: event_start must be a valid ISO 8601 timestamp")
}
end, err := parseISO8601(op.EventEnd)
if err != nil {
return fmt.Errorf("set_calendar: event_end must be a valid ISO 8601 timestamp")
}
if !end.After(start) {
return fmt.Errorf("set_calendar: event_end must be after event_start")
}
case "remove_calendar":
// No required fields.
default:
return fmt.Errorf("unsupported op %q", op.Op)
}
return nil
}
func isRecipientField(field string) bool {
switch strings.ToLower(strings.TrimSpace(field)) {
case "to", "cc", "bcc":
return true
default:
return falseView on GitHub (pinned to 7fd6ef3c07)
Solutions
- Reformat event_end to RFC 3339, e.g. 2026-09-04T11:00:00Z or with explicit offset 2026-09-04T11:00:00+08:00
- Convert epoch numbers first: time.Unix(sec).UTC().Format(time.RFC3339)
- Check that event_start and event_end are produced by the same formatting code path — often one is fixed while the other still uses a legacy format
- Pre-validate with time.Parse(time.RFC3339, s) client-side
Example fix
// before
end := fmt.Sprintf("%v", endTime) // "2026-09-04 11:00:00 +0800 CST"
// after
end := endTime.UTC().Format(time.RFC3339) // "2026-09-04T03:00:00Z" Defensive patterns
Strategy: validation
Validate before calling
func validTimestamp(s string) bool {
_, err := time.Parse(time.RFC3339, s)
return err == nil
}
if !validTimestamp(op.EventEnd) {
return fmt.Errorf("event_end must be RFC 3339, got %q", op.EventEnd)
} Prevention
- Format event_start and event_end with the same helper so one cannot drift out of spec
- Avoid Go default time formatting (%v) or database timestamp strings as wire values
- Convert epoch values explicitly with time.Unix(...).UTC().Format(time.RFC3339)
- Validate end separately from start — errors are reported per field
When it happens
Trigger: set_calendar op with event_end like '1725400000000' (epoch), '2026/09/04 11:00', '2026-09-04' (date-only), 'Fri Sep 04 2026 11:00:00 GMT+0800', or any string not matching one of the four time.Parse layouts in parseISO8601.
Common situations: Generating end times with a different formatter than start times; timezone libraries outputting offsets like '+08' (single-digit hours) instead of '+08:00'; serializing dates via fmt.Sprintf("%v", t) which yields a full Go date string the parser rejects.
Related errors
- set_calendar: event_start must be a valid ISO 8601 timestamp
- set_calendar: event_end must be after event_start
- unsupported op %q
- cannot parse %q as ISO 8601
- unsupported patch op %q
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/456cbe8b591519fa.
Report an issue: GitHub.