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

  1. Send the default_value as a JSON string, e.g. "default_value": "42" instead of 42
  2. Send an array of strings for multi-value defaults, e.g. "default_value": ["a","b"]
  3. 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

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


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)