{"record":{"id":"e3bc485d7b81f591","repo":"multica-ai/multica","slug":"value-must-be-a-date-string-in-yyyy-mm-dd-format","errorCode":null,"errorMessage":"value must be a date string in YYYY-MM-DD format","messagePattern":"value must be a date string in YYYY-MM-DD format","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"server/internal/handler/property.go","lineNumber":356,"sourceCode":"\t\tu, err := url.Parse(s)\n\t\tif err != nil || (u.Scheme != \"http\" && u.Scheme != \"https\") || u.Host == \"\" {\n\t\t\treturn nil, errors.New(\"value must be an http(s) URL\")\n\t\t}\n\t\treturn json.Marshal(s)\n\tcase \"number\":\n\t\tif _, ok := v.(float64); !ok {\n\t\t\treturn nil, errors.New(\"value must be a number\")\n\t\t}\n\t\treturn json.Marshal(v)\n\tcase \"checkbox\":\n\t\tif _, ok := v.(bool); !ok {\n\t\t\treturn nil, errors.New(\"value must be true or false\")\n\t\t}\n\t\treturn json.Marshal(v)\n\tcase \"date\":\n\t\ts, ok := v.(string)\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"value must be a date string in YYYY-MM-DD format\")\n\t\t}\n\t\tif _, err := time.Parse(\"2006-01-02\", s); err != nil {\n\t\t\treturn nil, errors.New(\"value must be a date string in YYYY-MM-DD format\")\n\t\t}\n\t\treturn json.Marshal(s)\n\tcase \"select\":\n\t\ts, ok := v.(string)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"value must be one of the option ids: %s\", selectOptionsHint(cfg))\n\t\t}\n\t\tif _, exists := propertyOptionIDs(cfg)[s]; !exists {\n\t\t\treturn nil, fmt.Errorf(\"value must be one of the option ids: %s\", selectOptionsHint(cfg))\n\t\t}\n\t\treturn json.Marshal(s)\n\tcase \"multi_select\":\n\t\titems, ok := v.([]any)\n\t\tif !ok || len(items) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"value must be a non-empty array of option ids: %s\", selectOptionsHint(cfg))","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/handler/property.go#L338-L374","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\n{ value: new Date() } // or \"2026-08-15T00:00:00.000Z\"\n// after\n{ value: \"2026-08-15\" }","handlingStrategy":"type-guard","validationCode":"if (def.type === 'date' && typeof value !== 'string') {\n  throw new Error('Date properties must be sent as YYYY-MM-DD strings');\n}","typeGuard":"function isDateString(v: unknown): v is string {\n  return typeof v === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(v);\n}","tryCatchPattern":null,"preventionTips":["Format Date objects to YYYY-MM-DD before sending","Never send epoch numbers to date properties","Slice ISO strings: toISOString().slice(0,10)"],"tags":["validation","date","issue-properties"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}