larksuite/cli · error

date column has an empty cell — drop the empty rows, fill re

Error message

date column has an empty cell — drop the empty rows, fill real yyyy-mm-dd dates, or declare the column dtype as object (text)

What it means

isoDateToSerial converts a date column's string into an Excel serial number. An empty (or whitespace-only) cell in a date-typed column cannot be converted, so this prescriptive error names the three ways out: drop the empty rows, provide real dates, or change the column dtype to object/text. Callers add row/column context.

Source

Thrown at shortcuts/sheets/lark_sheet_table_io.go:775

// isoDateToSerial converts an ISO yyyy-mm-dd string to its Excel serial day
// number. A time suffix is retained as a fractional day so table-get/table-put
// round-trips datetime-formatted cells without dropping the clock component.
//
// Accepts both bare dates (`2024-01-15`) and full ISO datetime strings with a
// `T` separator (`2024-01-15T00:00:00.000`, `2024-01-15T08:30:00+08:00`). The
// `T...` suffix is dropped before parsing so the pandas `df_to_sheet` helper
// — which uses `df.to_json(orient="split", date_format="iso")` and therefore
// always emits the full ISO form — round-trips without an extra string clean
// step on the agent side. A leading `T` (no date prefix) is left alone so the
// parser still rejects it cleanly.
func isoDateToSerial(s string) (float64, error) {
	s = strings.TrimSpace(s)
	if s == "" {
		// Empty cells in a date-typed column are the classic header/total-row
		// clash with the column-wide dtype declaration; name the three ways
		// out so the caller does not have to guess what "bad format" means.
		return 0, fmt.Errorf("date column has an empty cell — drop the empty rows, fill real yyyy-mm-dd dates, or declare the column dtype as object (text)") //nolint:forbidigo // intermediate error; callers wrap it into a typed --sheets/--values validation error with row/column context
	}
	if i := strings.Index(s, "T"); i > 0 {
		base := s[:i]
		date, err := time.Parse("2006-01-02", base)
		if err != nil {
			return 0, fmt.Errorf("date %q must be ISO yyyy-mm-dd: %w", base, err) //nolint:forbidigo // intermediate parse error; caller wraps it with typed validation context
		}
		var parsed time.Time
		clock := s[i:]
		if strings.ContainsAny(clock, "Zz+-") {
			parsed, err = time.Parse(time.RFC3339Nano, s)
		} else {
			parsed, err = time.Parse("2006-01-02T15:04:05.999999999", s)
		}
		if err != nil {
			return 0, fmt.Errorf("datetime %q must be ISO: %w", s, err) //nolint:forbidigo // intermediate parse error; caller wraps it with typed validation context
		}
		if parsed.Location() != time.UTC {

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Fill the empty cells with real yyyy-mm-dd dates (e.g. "2026-01-31")
  2. Remove the empty rows from the payload before putting
  3. Declare the column dtype as "object" (text) so blanks are stored as literal text

Example fix

// before
{"name":"Due","type":"date","data":["2026-01-31",""]}
// after
{"name":"Due","type":"date","data":["2026-01-31","2026-02-01"]}
// or dtype
{"name":"Due","type":"object","data":["2026-01-31",""]}
Defensive patterns

Strategy: validation

Validate before calling

function assertNoEmptyDates(col) {
  col.data.forEach((v, i) => {
    if (typeof v === 'string' && v.trim() === '')
      throw new Error(`column ${col.name} (date): row ${i} is empty; fill a yyyy-mm-dd date or use dtype object`);
  });
}

Type guard

function isFilledDate(v) { return typeof v === 'string' && v.trim() !== ''; }

Try / catch

try {
  await run(['lark','sheet','table-put','--sheets',payload]);
} catch (e) {
  if (/date column has an empty cell/.test(e.message)) {
    // drop empty rows, fill dates, or change dtype to "object" and retry
  }
  throw e;
}

Prevention

When it happens

Trigger: A --sheets/--values payload with a date column containing "" or " " in any row — typically a totals row, blank separator row, or partially filled table.

Common situations: Header/total rows that leave the date cell blank; CSV exports with empty trailing cells; sparse data where some records have no date yet.

Related errors


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