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

  1. Send a plain string: {"value": "2026-08-15"}
  2. Slice the ISO timestamp: date.toISOString().slice(0, 10)
  3. 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

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


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/e3bc485d7b81f591. Report an issue: GitHub.