antonmedv/fx · warning
<error from json.Marshal of the theme export map> (panic(err
Error message
<error from json.Marshal of the theme export map> (panic(err))
What it means
ExportThemes builds a map of theme data and serializes it with json.Marshal. If marshaling fails, it panics with the raw error instead of returning it. In practice json.Marshal of a map[string][]string built from well-typed theme extractors cannot fail, so this panic indicates an unexpected type reached the export map.
Source
Thrown at internal/theme/theme.go:444
if len(matches) == 0 {
return ""
} else {
return matches[1]
}
}
var export = map[string][]string{}
for _, name := range themeNames {
t := themes[name]
export[name] = append(export[name], extract(t.Syntax(placeholder)))
export[name] = append(export[name], extract(t.Key(placeholder)))
export[name] = append(export[name], extract(t.String(placeholder)))
export[name] = append(export[name], extract(t.Number(placeholder)))
export[name] = append(export[name], extract(t.Boolean(placeholder)))
export[name] = append(export[name], extract(t.Null(placeholder)))
}
data, err := json.Marshal(export)
if err != nil {
panic(err)
}
fmt.Println(string(data))
}
View on GitHub (pinned to 4f31cd3a0c)
Solutions
- Audit the values appended to export[name]; keep only strings, bools, nil, and other JSON-serializable types
- If custom types are needed, implement json.Marshaler on them
- Return the error instead of panicking so callers can report it cleanly
Example fix
// before
data, err := json.Marshal(export)
if err != nil {
panic(err)
}
// after
data, err := json.Marshal(export)
if err != nil {
return fmt.Errorf("marshaling theme export: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
// ensure export map holds only serializable values before marshaling
for name, vals := range export {
for _, v := range vals {
if _, err := json.Marshal(v); err != nil {
log.Fatalf("theme %q has non-serializable value: %v", name, err)
}
}
} Try / catch
// wrap the panic if calling ExportThemes programmatically
func safeExport() (out string, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("ExportThemes panicked: %v", r)
}
}()
ExportThemes()
return "", nil
} Prevention
- Keep the export map typed as map[string][]string or similar JSON-safe types
- Require json.Marshaler on any custom theme value type
- Add a unit test that marshals the export map for every built-in theme
When it happens
Trigger: json.Marshal returns an error for the export map — e.g. an unsupported value type (channel, func, cyclic structure) was appended to export[name] by a change to the extract() calls in ExportThemes.
Common situations: A contributor modifies ExportThemes to embed a non-serializable value (e.g. a func or a channel) into the export map; future theme entries holding custom types without MarshalJSON.
Related errors
- unsupported node kind %d
- <panics with the raw TOML input bytes (in) when toml.Unmarsh
- <error from io.ReadAll of input source> (panic(err))
- <error returned from pipeline p.Run()> (panic(err))
- <non-PathError from os.Open(filePath)> (panic(err))
AI-assisted analysis of antonmedv/fx@4f31cd3a0c (2026-09-02).
Data as JSON: /api/errors/7633f615df688004.
Report an issue: GitHub.