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
- Fill the empty cells with real yyyy-mm-dd dates (e.g. "2026-01-31")
- Remove the empty rows from the payload before putting
- 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
- Strip blank separator/totals rows from tabular data before put
- Pre-decide the policy for missing dates (fill sentinel, omit row, or text dtype)
- Validate payloads row-by-row before invoking the CLI
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
- date expects an ISO yyyy-mm-dd string, got %s
- expected pure digits (row number) or letters (column letter)
- number expects a numeric value, got %s
- bool expects true/false, got %s
- unsupported type %q
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/62484003138e0e90.
Report an issue: GitHub.