multica-ai/multica · error
value must be a date string in YYYY-MM-DD format
Error message
value must be a date string in YYYY-MM-DD format
What it means
validatePropertyValue rejects date-type property values that are not JSON strings; the date must be a string in strict YYYY-MM-DD form. This branch fires when the client sends a number (epoch), object, or array where the definition type is "date". A string that fails Go's time.Parse("2006-01-02") hits the duplicate check at line 359 instead.
Source
Thrown at server/internal/handler/property.go:356
u, err := url.Parse(s)
if err != nil || (u.Scheme != "http" && u.Scheme != "https") || u.Host == "" {
return nil, errors.New("value must be an http(s) URL")
}
return json.Marshal(s)
case "number":
if _, ok := v.(float64); !ok {
return nil, errors.New("value must be a number")
}
return json.Marshal(v)
case "checkbox":
if _, ok := v.(bool); !ok {
return nil, errors.New("value must be true or false")
}
return json.Marshal(v)
case "date":
s, ok := v.(string)
if !ok {
return nil, errors.New("value must be a date string in YYYY-MM-DD format")
}
if _, err := time.Parse("2006-01-02", s); err != nil {
return nil, errors.New("value must be a date string in YYYY-MM-DD format")
}
return json.Marshal(s)
case "select":
s, ok := v.(string)
if !ok {
return nil, fmt.Errorf("value must be one of the option ids: %s", selectOptionsHint(cfg))
}
if _, exists := propertyOptionIDs(cfg)[s]; !exists {
return nil, fmt.Errorf("value must be one of the option ids: %s", selectOptionsHint(cfg))
}
return json.Marshal(s)
case "multi_select":
items, ok := v.([]any)
if !ok || len(items) == 0 {
return nil, fmt.Errorf("value must be a non-empty array of option ids: %s", selectOptionsHint(cfg))View on GitHub (pinned to 2c0912b6ec)
Solutions
- Send a plain string: {"value": "2026-08-15"}
- Slice the ISO timestamp: date.toISOString().slice(0, 10)
- Build the string from local parts if timezone drift matters: use the user's local date, not UTC, before formatting
Example fix
// before
{ value: new Date() } // or "2026-08-15T00:00:00.000Z"
// after
{ value: "2026-08-15" } Defensive patterns
Strategy: type-guard
Validate before calling
if (def.type === 'date' && typeof value !== 'string') {
throw new Error('Date properties must be sent as YYYY-MM-DD strings');
} Type guard
function isDateString(v: unknown): v is string {
return typeof v === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(v);
} Prevention
- Format Date objects to YYYY-MM-DD before sending
- Never send epoch numbers to date properties
- Slice ISO strings: toISOString().slice(0,10)
When it happens
Trigger: PUT/PATCH a date property with {"value": 1735689600000} (epoch millis), {"value": {"year":2026,"month":8,"day":15}}, or a Date object serialized to an ISO timestamp with time/timezone components when the string is later parsed (that path errors at line 359).
Common situations: JS clients sending Date.toJSON() output ("2026-08-15T00:00:00.000Z") instead of the date part; epoch-based APIs; component libraries returning Luxon/Dayjs objects.
Related errors
- value cannot be empty (use DELETE to unset a property)
- value must be a URL string
- value must be an http(s) URL
- value must be a number
- value must be true or false
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/e3bc485d7b81f591.
Report an issue: GitHub.