{"record":{"id":"2203b02dd1a72c65","repo":"semaphoreui/semaphore","slug":"values-must-be-scalar","errorCode":null,"errorMessage":"values must be scalar","messagePattern":"values must be scalar","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db/Environment.go","lineNumber":100,"sourceCode":"\tif s == \"\" {\n\t\treturn nil\n\t}\n\n\tvar data map[string]any\n\terr := json.Unmarshal([]byte(s), &data)\n\tif err != nil {\n\t\treturn errors.New(\"must be valid JSON\")\n\t}\n\n\tfor k, v := range data {\n\t\tif k == \"\" {\n\t\t\treturn errors.New(\"key can not be empty\")\n\t\t}\n\n\t\tif mustValuesBeScalar {\n\t\t\tswitch v.(type) {\n\t\t\tcase []any, map[string]any:\n\t\t\t\treturn errors.New(\"values must be scalar\")\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (env *Environment) Validate() (err error) {\n\tif env.Name == \"\" {\n\t\terr = common_errors.NewValidationError(\"Environment name can not be empty\")\n\t\treturn\n\t}\n\n\terr = validateJSON(env.JSON, false)\n\tif err != nil {\n\t\terr = common_errors.NewValidationError(\"Extra variables \" + err.Error())\n\t\treturn\n\t}","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/db/Environment.go#L82-L118","documentation":"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.","triggerScenarios":"Environment payload like {\"CFG\": {\"a\": 1}} or {\"LIST\": [1,2]} submitted where scalar-only values are enforced (validated by Validate on environment create/update).","commonSituations":"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.","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"],"exampleFix":"// before\n{\"DB\": {\"host\": \"localhost\", \"port\": 5432}}\n// after\n{\"DB_HOST\": \"localhost\", \"DB_PORT\": \"5432\"}","handlingStrategy":"validation","validationCode":"for k, v := range payload {\n\tswitch v.(type) {\n\tcase []any, map[string]any:\n\t\treturn fmt.Errorf(\"env var %s must be scalar\", k)\n\t}\n}","typeGuard":"func allScalars(m map[string]any) bool {\n\tfor _, v := range m {\n\t\tswitch v.(type) {\n\t\tcase []any, map[string]any:\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","tryCatchPattern":"if err := env.Validate(); err != nil {\n\tif strings.Contains(err.Error(), \"values must be scalar\") {\n\t\treturn fmt.Errorf(\"environment rejected: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["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"],"tags":["go","json","validation","environment"],"backgroundTag":"schema-validation-failed","analyzedSha":"1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa","analyzedAt":"2026-09-07T11:00:33.293Z","contentChangedAt":"2026-09-07T11:00:33.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}