gotify/server · error
invalid JSON for %s: %w
Error message
invalid JSON for %s: %w
What it means
parseMap unmarshals a JSON-encoded environment/config value into a map[string]string. When json.Unmarshal fails because the raw string is not a valid JSON object with string values, it wraps the underlying error with the environment variable name for context.
Source
Thrown at config/parse.go:103
record, err := reader.Read()
if err != nil {
return fmt.Errorf("invalid CSV for %s (%q): %w", env, raw, err)
}
*target = record
return nil
}
func parseMap(target *map[string]string, env string) error {
raw, ok, err := lookupEnv(env)
if err != nil {
return err
}
if !ok || raw == "" {
return nil
}
out := map[string]string{}
if err := json.Unmarshal([]byte(raw), &out); err != nil {
return fmt.Errorf("invalid JSON for %s: %w", env, err)
}
*target = out
return nil
}
func parseLogLevel(target *LogLevel, env string) error {
raw, ok, err := lookupEnv(env)
if err != nil {
return err
}
if !ok {
return nil
}
return target.Decode(raw)
}
View on GitHub (pinned to 14bfc25627)
Solutions
- Fix the env var value to be a valid JSON object with only string values, e.g. {"key":"value"}
- Validate the JSON locally (e.g. echo '<value>' | jq .) before deploying
- If the value is meant to be a plain string, use the appropriate non-map accessor instead of the map parser
Example fix
// before
MY_MAP={'a':'b'}
// after
MY_MAP={"a":"b"} Defensive patterns
Strategy: validation
Validate before calling
raw := os.Getenv("MY_MAP")
if raw != "" {
var probe map[string]string
if err := json.Unmarshal([]byte(raw), &probe); err != nil {
return fmt.Errorf("MY_MAP is not valid JSON: %w", err)
}
} Try / catch
m, err := cfg.Get("MY_MAP")
if err != nil {
var je *json.SyntaxError
if errors.As(err, &je) {
log.Fatalf("fix MY_MAP JSON near offset %d", je.Offset)
}
return err
} Prevention
- Always use double-quoted, valid JSON for map-type env vars
- Validate JSON values in CI before deployment
- Use a JSON linter or jq to check values
- Prefer dedicated scalar accessors for non-map values
When it happens
Trigger: Get is called for a config key whose raw env value is non-empty but is not a valid JSON object, e.g. a value missing quotes around keys, using single quotes, trailing commas, or containing non-string values.
Common situations: Developers set env vars like FOO_MAP={"a":1} (integer value) or FOO_MAP={'a':'b'} (single quotes from shell habits) instead of strictly valid JSON with string values: {"a":"b"}.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- username claim was empty
- unknown log level
- migrate-config requires one argument: the path to the old co
- read file for %s_FILE (%s): %w
- invalid int for %s (%q): %w
AI-assisted analysis of gotify/server@14bfc25627 (2026-09-05).
Data as JSON: /api/errors/1a576fcf04000732.
Report an issue: GitHub.