semaphoreui/semaphore · error

key can not be empty

Error message

key can not be empty

What it means

validateJSON iterates the parsed environment JSON object and rejects it if any key is the empty string. Empty keys cannot be exported as environment variables, so an entry like {"": "value"} is caught during environment validation rather than failing silently at job runtime.

Solutions

  1. Remove entries with empty keys from the environment JSON payload
  2. Templating tools: skip or fail on empty variable names instead of emitting an empty key
  3. Validate keys with a quick client-side check (all object keys non-empty) before calling the API

Example fix

// before
{"": "value"}
// after
{"MY_VAR": "value"}
Defensive patterns

Strategy: validation

Validate before calling

for k := range payload {
	if k == "" {
		return errors.New("environment payload contains an empty key")
	}
}

Type guard

func hasNoEmptyKeys(m map[string]any) bool {
	for k := range m {
		if k == "" { return false }
	}
	return true
}

Try / catch

if err := env.Validate(); err != nil {
	if strings.Contains(err.Error(), "key can not be empty") {
		return fmt.Errorf("environment rejected: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Environment payload JSON containing an entry with an empty key (e.g. {"": "..."} or {" ": ...} is not caught, but literal "" is), typically produced by templating where the variable name variable is empty.

Common situations: Ansible/Jinja templating emitting entries for undefined variable names; CSV-to-JSON converters producing empty keys for blank rows; manual editing mistakes in the environment JSON editor.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07). Data as JSON: /api/errors/ecef2e39b7a67cce. Report an issue: GitHub.

Appendix: source

Thrown at db/Environment.go:94

	}

	return errors.New("invalid environment secret type")
}

func validateJSON(s string, mustValuesBeScalar bool) error {
	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
	}

View on GitHub (pinned to 1774ccb71a)