semaphoreui/semaphore · error
values must be scalar
Error message
values must be scalar
What it means
When mustValuesBeScalar is true, validateJSON rejects environment JSON objects whose values are arrays or nested objects. Environment variables must be flat scalar strings so they can be exported directly into the job's process environment; complex structures are not representable as env vars.
Solutions
- Flatten nested objects into scalar keys (e.g. CFG_A: "1") before submitting
- Serialize complex values to a string (JSON/base64) and store as a single scalar variable
- Store complex config in a file/repository artifact or a secret instead of environment variables
Example fix
// before
{"DB": {"host": "localhost", "port": 5432}}
// after
{"DB_HOST": "localhost", "DB_PORT": "5432"} Defensive patterns
Strategy: validation
Validate before calling
for k, v := range payload {
switch v.(type) {
case []any, map[string]any:
return fmt.Errorf("env var %s must be scalar", k)
}
} Type guard
func allScalars(m map[string]any) bool {
for _, v := range m {
switch v.(type) {
case []any, map[string]any:
return false
}
}
return true
} Try / catch
if err := env.Validate(); err != nil {
if strings.Contains(err.Error(), "values must be scalar") {
return fmt.Errorf("environment rejected: %w", err)
}
return err
} Prevention
- Flatten nested config into KEY_SUBKEY scalar entries
- Serialize complex values to JSON/base64 strings when needed as env vars
- Enforce map[string]string typing on env payloads in client code
When it happens
Trigger: Environment payload like {"CFG": {"a": 1}} or {"LIST": [1,2]} submitted where scalar-only values are enforced (validated by Validate on environment create/update).
Common situations: Users pasting nested JSON config blobs as environment variables; tools serializing maps/lists of settings into the env payload; migrating from another CI that allows nested env values.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- must be valid JSON
- key can not be empty
- missing secret
- invalid environment secret type
- secret must be valid json in key
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/2203b02dd1a72c65.
Report an issue: GitHub.
Appendix: source
Thrown at db/Environment.go:100
if s == "" {
return nil
}
var data map[string]any
err := json.Unmarshal([]byte(s), &data)
if err != nil {
return errors.New("must be valid JSON")
}
for k, v := range data {
if k == "" {
return errors.New("key can not be empty")
}
if mustValuesBeScalar {
switch v.(type) {
case []any, map[string]any:
return errors.New("values must be scalar")
}
}
}
return nil
}
func (env *Environment) Validate() (err error) {
if env.Name == "" {
err = common_errors.NewValidationError("Environment name can not be empty")
return
}
err = validateJSON(env.JSON, false)
if err != nil {
err = common_errors.NewValidationError("Extra variables " + err.Error())
return
}View on GitHub (pinned to 1774ccb71a)