multica-ai/multica · error
value cannot be empty (use DELETE to unset a property)
Error message
value cannot be empty (use DELETE to unset a property)
What it means
Thrown by validatePropertyValue in the Multica server when a property of type "text" is set to a string that is empty or only whitespace. The API treats JSON null as 'unset this property' and rejects empty strings instead of silently clearing them, so unsetting must go through the DELETE verb. It is returned as a 400-class validation error from the issue property update endpoint.
Source
Thrown at server/internal/handler/property.go:323
return nil, errors.New("value is required")
}
var v any
if err := json.Unmarshal(raw, &v); err != nil {
return nil, fmt.Errorf("value must be valid JSON: %w", err)
}
if v == nil {
return nil, errors.New("value cannot be null (use DELETE to unset a property)")
}
cfg := parsePropertyConfig(def.Config)
switch def.Type {
case "text":
s, ok := v.(string)
if !ok {
return nil, errors.New("value must be a string")
}
if strings.TrimSpace(s) == "" {
return nil, errors.New("value cannot be empty (use DELETE to unset a property)")
}
if utf8.RuneCountInString(s) > maxPropertyTextValueLen {
return nil, fmt.Errorf("value must be %d characters or fewer", maxPropertyTextValueLen)
}
return json.Marshal(sanitizeNullBytes(s))
case "url":
s, ok := v.(string)
if !ok {
return nil, errors.New("value must be a URL string")
}
s = strings.TrimSpace(s)
if len(s) > maxPropertyURLValueLen {
return nil, fmt.Errorf("value must be %d characters or fewer", maxPropertyURLValueLen)
}
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")
}View on GitHub (pinned to 2c0912b6ec)
Solutions
- Send JSON null (or omit value) to clear the field, or use the DELETE endpoint for the property
- Guard in the client: if the trimmed text is empty, issue DELETE instead of a value update
- Keep a non-empty placeholder value if the property is required by workflow
Example fix
// before
await api.updateIssueProperty(issueId, propId, { value: "" });
// after
await api.deleteIssueProperty(issueId, propId); // or send { value: null } per API contract Defensive patterns
Strategy: validation
Validate before calling
const v = req.value;
if (typeof v === 'string' && v.trim() === '') {
// empty text means unset -> route to DELETE
await api.deleteIssueProperty(issueId, propId);
return;
} Type guard
function isEmptyTextValue(v: unknown): boolean {
return typeof v === 'string' && v.trim() === '';
} Try / catch
try { await api.updateIssueProperty(id, propId, { value }); }
catch (e) {
if (e.status === 400 && /cannot be empty/.test(e.message)) await api.deleteIssueProperty(id, propId);
else throw e;
} Prevention
- Treat empty string and null differently in property forms: empty means DELETE
- Trim-then-check before building the request payload
- Map blank CSV/import cells to null, not ''
When it happens
Trigger: PUT/PATCH on an issue property whose definition type is "text" with req.Value = "" or " " (e.g. {"value": ""} in the property value update payload handled at property.go:762). Happens when a form submits an untouched-but-touched-and-cleared input, or when code trims a value to nothing before sending.
Common situations: Frontend forms that send the current field value on blur/save even when the user cleared it; import scripts mapping blank CSV cells to empty strings instead of null; a toggle from 'has value' to 'cleared' implemented as empty-string instead of DELETE.
Related errors
- value must be a URL string
- value must be an http(s) URL
- value must be a number
- value must be true or false
- value must be a date string in YYYY-MM-DD format
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/355165530257c66d.
Report an issue: GitHub.