Billionmail/BillionMail · error
error marshalling images: %v
Error message
error marshalling images: %v
What it means
SaveImagesConfig serializes a []ImageInfo slice with json.MarshalIndent and writes it to PRODUCT_CONFIG_PATH/<Domain>/images.json. This error is returned when json.MarshalIndent fails on the images slice. Like error 197, this only happens if ImageInfo (or its fields) contains values json cannot encode — unsupported types, cyclic references, or channels/funcs — since a plain slice of structs marshals fine.
Source
Thrown at core/internal/service/askai/project.go:896
type BotStyle struct {
AccentColor string `json:"accent_color"`
BodyFont string `json:"body_font"`
ContainerBackground string `json:"container_background"`
HeadingFont string `json:"heading_font"`
LinkFooterColor string `json:"link_footer_color"`
LinkSocialColor string `json:"link_social_color"`
PageBackground string `json:"page_background"`
TextColor string `json:"text_color"`
}
func SaveImagesConfig(Domain string, images []ImageInfo) error {
imagesPath := fmt.Sprintf("%s/%s/images.json", PRODUCT_CONFIG_PATH, Domain)
if !public.FileExists(PRODUCT_CONFIG_PATH + "/" + Domain) {
os.MkdirAll(PRODUCT_CONFIG_PATH+"/"+Domain, os.ModePerm)
}
data, err := json.MarshalIndent(images, "", " ")
if err != nil {
return fmt.Errorf("error marshalling images: %v", err)
}
err = os.WriteFile(imagesPath, data, 0644)
if err != nil {
return fmt.Errorf("error saving images file: %v", err)
}
return nil
}
func ReadImagesConfig(Domain string) ([]ImageInfo, error) {
imagesPath := fmt.Sprintf("%s/%s/images.json", PRODUCT_CONFIG_PATH, Domain)
if !public.FileExists(imagesPath) {
os.WriteFile(imagesPath, []byte("[]"), 0644)
}
data, err := os.ReadFile(imagesPath)
if err != nil {
return []ImageInfo{}, fmt.Errorf("error reading images configuration file: %v", err)
}
View on GitHub (pinned to fc36c76c05)
Solutions
- Read the wrapped 'json: unsupported type: ...' message to identify the failing type
- Add json:"-" to non-serializable ImageInfo fields or implement MarshalJSON on them
- Replace unsupported fields with serializable equivalents (string IDs, plain structs)
- Guard against cycles by storing indices/IDs instead of self-referencing pointers
Example fix
// before
type ImageInfo struct {
URL string `json:"url"`
Loader func() // causes: json: unsupported type: func()
}
// after
type ImageInfo struct {
URL string `json:"url"`
Loader func() `json:"-"`
} Defensive patterns
Strategy: validation
Validate before calling
// validate images slice is serializable before SaveImagesConfig
func imagesAreSerializable(images []ImageInfo) error {
_, err := json.Marshal(images)
return err
}
// usage:
if err := imagesAreSerializable(images); err != nil {
log.Printf("images not serializable, fix ImageInfo fields: %v", err)
} Try / catch
if err := SaveImagesConfig(domain, images); err != nil {
if strings.Contains(err.Error(), "marshalling images") {
log.Printf("ImageInfo contains unsupported field type: %v", err)
// sanitize: strip non-serializable fields and retry
return err
}
return err
} Prevention
- Tag non-serializable ImageInfo fields with json:"-"
- Add a unit test marshalling a representative []ImageInfo
- Keep ImageInfo free of funcs, channels, and cyclic pointers
- Prefer storing plain data (URLs, IDs, dimensions) in persisted image records
When it happens
Trigger: Calling SaveImagesConfig(domain, images) where an ImageInfo field (or nested struct) is a func, channel, or contains a reference cycle, causing json.MarshalIndent to return 'json: unsupported type'.
Common situations: A developer extended ImageInfo with a non-serializable field (handler, connection, sync.Mutex used carelessly in a cycle) without a json:"-" tag or custom MarshalJSON, then saved the images config.
Related errors
- error marshalling prompt config: %v
- failed to unmarshal tool call arguments: %v, %s
- error unmarshalling project configuration: %v
- error marshalling project configuration: %v
- error unmarshalling knowledge base: %v
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/2a07f4724ee05901.
Report an issue: GitHub.