semaphoreui/semaphore · critical
Could not decode configuration!
Error message
Could not decode configuration!
What it means
The JSON config file decoder could not parse config.json into the global Config struct. Semaphore prints 'Could not decode configuration!' and panics with the underlying json error. This means the configuration file is syntactically invalid JSON or has incompatible types for known fields.
Solutions
- Validate the file with `jq . /path/to/config.json` (or any JSON linter) and fix syntax errors
- If the file is actually YAML, rename it to config.yml or add the .yaml/.yml extension so the YAML decoder is used
- Check field types against the ConfigType struct (objects, not strings, for mysql/postgres blocks)
- Restore a known-good config.json from backup or `semaphore setup` output
Example fix
// before (config.json with trailing comma)
{"mysql": {"host": "db",},}
// after
{"mysql": {"host": "db"}} Defensive patterns
Strategy: validation
Validate before calling
// validate JSON config before handing it to semaphore
jq -e . /etc/semaphore/config.json > /dev/null || { echo 'invalid JSON'; exit 1; } Try / catch
// wrap decodeConfigFile in recover to convert panic to error
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("config decode failed: %v", r)
}
}() Prevention
- Always `jq . config.json` after hand edits
- Never put comments or trailing commas in config.json
- Name YAML configs with .yml/.yaml so the right decoder is used
- Keep config.json in version control to diff against a known-good copy
When it happens
Trigger: decodeConfigFile opens a non-YAML config path and json.NewDecoder(file).Decode(&Config) fails: trailing commas, comments, single quotes, wrong types (e.g. string where object expected), or truncated file.
Common situations: Hand-edited config.json with a stray comma or comment; config written as YAML but named config.json (or missing .yml extension so the YAML branch is skipped); partially-written file from a failed deploy.
Related errors
- expected slice or json array string for field
- cannot assign value of type
- got non-existent config attribute
- got non-existent config attribute
- database configuration not found
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/bb15e8735c6f69a6.
Report an issue: GitHub.
Appendix: source
Thrown at util/config.go:1894
func exitOnConfigError(msg string) {
fmt.Println(msg)
os.Exit(1)
}
func exitOnConfigFileError(err error) {
if err != nil {
exitOnConfigError("Cannot Find configuration! Use --config parameter to point to a JSON or YAML file generated by `semaphore setup`.")
}
}
func decodeConfig(file io.Reader, configPath string) {
if isYAMLConfig(configPath) {
decodeConfigYAML(file)
return
}
if err := json.NewDecoder(file).Decode(&Config); err != nil {
fmt.Println("Could not decode configuration!")
panic(err)
}
}
func isYAMLConfig(configPath string) bool {
ext := strings.ToLower(filepath.Ext(configPath))
return ext == ".yaml" || ext == ".yml"
}
func decodeConfigYAML(file io.Reader) {
var raw any
if err := yaml.NewDecoder(file).Decode(&raw); err != nil {
fmt.Println("Could not decode configuration!")
panic(err)
}
data, err := json.Marshal(raw)
if err != nil {
fmt.Println("Could not decode configuration!")
panic(err)View on GitHub (pinned to 1774ccb71a)