semaphoreui/semaphore · error
invalid default_value: must be string or []string
Error message
invalid default_value: must be string or []string
What it means
SurveyVarDefaultValue.UnmarshalJSON accepts either a JSON string or an array of strings for the default_value field. Any other JSON type (number, bool, object) produces 'invalid default_value: must be string or []string'. The custom unmarshaler also tracks whether the original value was an array.
Solutions
- Send the default_value as a JSON string, e.g. "default_value": "42" instead of 42
- Send an array of strings for multi-value defaults, e.g. "default_value": ["a","b"]
- Fix the client/serializer to stringify non-string defaults before submitting the template
Example fix
// before
{"name": "count", "default_value": 5}
// after
{"name": "count", "default_value": "5"} Defensive patterns
Strategy: validation
Validate before calling
func validDefaultValue(v any) bool {
switch t := v.(type) {
case string:
return true
case []any:
for _, e := range t {
if _, ok := e.(string); !ok { return false }
}
return true
}
return false
} Try / catch
if err := json.Unmarshal(body, &tpl); err != nil {
if strings.Contains(err.Error(), "invalid default_value") {
http.Error(w, "default_value must be a string or []string", http.StatusBadRequest)
return
}
http.Error(w, err.Error(), http.StatusBadRequest)
} Prevention
- Serialize survey defaults as strings or string arrays only
- Stringify numbers/booleans on the client before submitting templates
- Add JSON schema validation on template payloads
When it happens
Trigger: POST/PUT of a template whose survey variable default_value is a number, boolean, or nested object, e.g. {"default_value": 42} or {"default_value": {"a":1}}.
Common situations: API clients sending defaults for number/boolean survey vars without quoting them; UI forms submitting raw JS values; schema changes where defaults were previously untyped.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- expected bool for field, got %T
- expected string for field, got %T
- expected number for field, got %T
- expected object for struct, got %T
- must be valid JSON
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/1f12ef2f8f4176fd.
Report an issue: GitHub.
Appendix: source
Thrown at db/Template.go:118
}
// try string
var s string
if err := json.Unmarshal(b, &s); err == nil {
d.Values = []string{s}
d.originalWasArray = false
return nil
}
// try []string
var arr []string
if err := json.Unmarshal(b, &arr); err == nil {
d.Values = arr
d.originalWasArray = true
return nil
}
return fmt.Errorf("invalid default_value: must be string or []string")
}
func (d SurveyVarDefaultValue) MarshalJSON() ([]byte, error) {
if d.Values == nil {
return []byte("null"), nil
}
if len(d.Values) == 1 && !d.originalWasArray {
return json.Marshal(d.Values[0])
}
return json.Marshal(d.Values)
}
func (d SurveyVarDefaultValue) String() string {
if len(d.Values) == 0 {
return ""
}
return d.Values[0]
}View on GitHub (pinned to 1774ccb71a)