{"record":{"id":"7bc257a1ab853b8b","repo":"multica-ai/multica","slug":"value-must-be-a-number","errorCode":null,"errorMessage":"value must be a number","messagePattern":"value must be a number","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"server/internal/handler/property.go","lineNumber":345,"sourceCode":"\t\t}\n\t\treturn json.Marshal(sanitizeNullBytes(s))\n\tcase \"url\":\n\t\ts, ok := v.(string)\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"value must be a URL string\")\n\t\t}\n\t\ts = strings.TrimSpace(s)\n\t\tif len(s) > maxPropertyURLValueLen {\n\t\t\treturn nil, fmt.Errorf(\"value must be %d characters or fewer\", maxPropertyURLValueLen)\n\t\t}\n\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)","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/handler/property.go#L327-L363","documentation":"validatePropertyValue requires number-type property values to arrive as a JSON number, which Go's encoding/json decodes into float64. Sending the number as a string, boolean, object, or array fails this type assertion. Note the code does no range or integer check — only the JSON type matters.","triggerScenarios":"PUT/PATCH a number property with {\"value\": \"42\"} (quoted), {\"value\": true}, or {\"value\": {\"n\": 42}}. Typical when HTML form inputs produce strings and the client forgets to parse them, or a strict-typed client sends BigInt as a string.","commonSituations":"Form submissions where quantity/estimate fields arrive as text; spreadsheet imports mapping cells to strings; JSON.stringify of values already stringified once.","solutions":["Send a raw JSON number: {\"value\": 42} not {\"value\": \"42\"}","Parse form input with Number(...) before building the payload","For values exceeding float64 precision, be aware the backend stores float64 — round or clamp client-side"],"exampleFix":"// before\n{ value: \"42\" }\n// after\n{ value: 42 }","handlingStrategy":"type-guard","validationCode":"if (def.type === 'number') {\n  const n = Number(value);\n  if (Number.isNaN(n)) throw new Error('Property expects a JSON number');\n  payload.value = n;\n}","typeGuard":"function isNumberPropertyValue(v: unknown): v is number {\n  return typeof v === 'number' && Number.isFinite(v);\n}","tryCatchPattern":null,"preventionTips":["Parse form strings with Number() before JSON.stringify","Never quote numeric fields in payloads","Remember the backend stores float64 — avoid >2^53 integers"],"tags":["validation","number","issue-properties"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}