{"record":{"id":"4e9e7df237ff4318","repo":"Billionmail/BillionMail","slug":"error-unmarshalling-images-configuration-v","errorCode":null,"errorMessage":"error unmarshalling images configuration: %v","messagePattern":"error unmarshalling images configuration: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/askai/project.go","lineNumber":918,"sourceCode":"\t\treturn fmt.Errorf(\"error saving images file: %v\", err)\n\t}\n\treturn nil\n}\n\nfunc ReadImagesConfig(Domain string) ([]ImageInfo, error) {\n\timagesPath := fmt.Sprintf(\"%s/%s/images.json\", PRODUCT_CONFIG_PATH, Domain)\n\tif !public.FileExists(imagesPath) {\n\t\tos.WriteFile(imagesPath, []byte(\"[]\"), 0644)\n\t}\n\tdata, err := os.ReadFile(imagesPath)\n\tif err != nil {\n\t\treturn []ImageInfo{}, fmt.Errorf(\"error reading images configuration file: %v\", err)\n\t}\n\n\tvar images []ImageInfo\n\terr = json.Unmarshal(data, &images)\n\tif err != nil {\n\t\treturn []ImageInfo{}, fmt.Errorf(\"error unmarshalling images configuration: %v\", err)\n\t}\n\treturn images, nil\n}\n\ntype UploadImageResponse struct {\n\tStatus bool   `json:\"status\"`\n\tMsg    string `json:\"msg\"`\n\tData   struct {\n\t\tURL string `json:\"url\"`\n\t} `json:\"data\"`\n}\n\n// UploadImage(req.Domain, req.Image, req.Filename, req.AltText, req.ImageTag)\nfunc UploadImage(Domain string, Image string, Filename string, AltText string, ImageTag string) (string, error) {\n\timageInfo := ImageInfo{\n\t\tImageId:    GetUUID(),\n\t\tImageUrl:   \"\",\n\t\tFilename:   Filename,","sourceCodeStart":900,"sourceCodeEnd":936,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/askai/project.go#L900-L936","documentation":"ReadImagesConfig returns this when the images.json file exists but json.Unmarshal cannot parse it into []ImageInfo. It means the persisted JSON is corrupted, truncated, or no longer matches the ImageInfo schema (e.g. a field changed type).","triggerScenarios":"Calling ReadImagesConfig when images.json contains malformed JSON (partial write from a concurrent save/crash), a different top-level shape (object instead of array), or fields whose types changed in a new ImageInfo version.","commonSituations":"Two processes writing images.json concurrently without locking, a crash mid-write producing a truncated file, manual edits to the file, or an upgrade that changed ImageInfo field types.","solutions":["Inspect/validate images.json (jq . <path>) and repair or delete it so the code re-seeds '[]'.","Write atomically (write temp file + rename) in SaveImagesConfig to prevent truncated files.","Serialize writes to images.json with a file lock or single-writer goroutine.","On unmarshal failure, back up the corrupt file and fall back to an empty slice with a warning if acceptable."],"exampleFix":"// before\nvar images []ImageInfo\nerr = json.Unmarshal(data, &images)\nif err != nil {\n\treturn []ImageInfo{}, fmt.Errorf(\"error unmarshalling images configuration: %v\", err)\n}\n// after\nvar images []ImageInfo\nif err := json.Unmarshal(data, &images); err != nil {\n\t_ = os.Rename(imagesPath, imagesPath+\".corrupt\")\n\treturn []ImageInfo{}, fmt.Errorf(\"error unmarshalling images configuration: %v\", err)\n}","handlingStrategy":"validation","validationCode":"func validImagesJSON(path string) bool {\n\tdata, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn false\n\t}\n\tvar v []ImageInfo\n\treturn json.Unmarshal(data, &v) == nil\n}\n// if !validImagesJSON(imagesPath) { repair or reset before calling ReadImagesConfig }","typeGuard":"func isImageInfoSlice(b []byte) bool {\n\tvar v []ImageInfo\n\treturn len(b) > 0 && json.Unmarshal(b, &v) == nil\n}","tryCatchPattern":"images, err := ReadImagesConfig(domain)\nif err != nil && strings.Contains(err.Error(), \"unmarshalling images configuration\") {\n\tos.Rename(imagesPath, imagesPath+\".corrupt\")\n\timages = []ImageInfo{}\n}","preventionTips":["Write images.json atomically (temp + rename)","Serialize writers with a file lock","Never hand-edit the file in production without validating with jq","Back up the file before version upgrades that change ImageInfo"],"tags":["json","config-persistence","data-corruption"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}