{"record":{"id":"7edb6ea4a3dc051d","repo":"kovidgoyal/kitty","slug":"failed-to-read-cached-image-metadata-w","errorCode":null,"errorMessage":"failed to read cached image metadata: %w","messagePattern":"failed to read cached image metadata: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kittens/choose_files/image_preview.go","lineNumber":94,"sourceCode":"\nfunc (p *ImagePreview) String() string {\n\treturn fmt.Sprintf(\"ImagePreview{%#v, ready: %v, renderer: %s}\", p.abspath, p.ready.Load(), p.renderer.String())\n}\nfunc (p *ImagePreview) IsValidForColorScheme(bool) bool { return true }\nfunc (p *ImagePreview) IsReady() bool                   { return p.ready.Load() || p.render_channel == nil }\n\nfunc (p *ImagePreview) Unload() {\n\tp.source_img = nil\n}\n\nfunc load_image(cached_data map[string]string) (img *images.ImageData, err error) {\n\tfp := cached_data[IMAGE_METADATA_KEY]\n\tif fp == \"\" {\n\t\treturn nil, fmt.Errorf(\"missing cached image metadata\")\n\t}\n\tb, err := os.ReadFile(fp)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read cached image metadata: %w\", err)\n\t}\n\tvar m images.SerializableImageMetadata\n\tif err = json.Unmarshal(b, &m); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode cached image metadata: %w\", err)\n\t}\n\tframes := make([][]byte, len(m.Frames))\n\tfor i := range m.Frames {\n\t\tpath := cached_data[IMAGE_DATA_PREFIX+strconv.Itoa(i)]\n\t\tif path == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"missing cached data for frame: %d\", i)\n\t\t}\n\t\td, e := os.ReadFile(path)\n\t\tif e != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read cached image frame %d data: %w\", i, e)\n\t\t}\n\t\tm.Frames[i].Size = len(d)\n\t\tframes[i] = d\n\t}","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kittens/choose_files/image_preview.go#L76-L112","documentation":"load_image failed to os.ReadFile the file path stored under the IMAGE_METADATA_KEY entry of the kitten's cached data map. The metadata file path comes from a previous render's cache, so the read fails when that file was deleted, moved, or is unreadable (permissions, expired temp file).","triggerScenarios":"Calling RenderImagePreview or ensure_source_image after the cached metadata JSON file referenced by cached_data[IMAGE_METADATA_KEY] no longer exists or cannot be read (e.g. kitty's cache dir was cleaned between renders).","commonSituations":"Temp/cache directory cleaned by OS or user while a choose-files preview is still active; multi-instance kittens sharing cache paths; file removed by another process.","solutions":["Retry the render without the cache (delete the stale cache entry so the image is re-rendered from source)","Verify the path in cached_data[IMAGE_METADATA_KEY] exists before calling load_image","Check permissions on the kitty cache directory"],"exampleFix":"// before\nb, err := os.ReadFile(fp)\n// after\nif _, err := os.Stat(fp); err != nil {\n    return nil, fmt.Errorf(\"cached metadata missing, re-render needed: %w\", err)\n}\nb, err := os.ReadFile(fp)","handlingStrategy":"validation","validationCode":"if fp := cached_data[IMAGE_METADATA_KEY]; fp != \"\" { if _, err := os.Stat(fp); err != nil { /* drop cache, re-render */ } }","typeGuard":null,"tryCatchPattern":"In Go: if err != nil && errors.Is(err, fs.ErrNotExist) { invalidate cache; fall back to full render } else { return err }","preventionTips":["Stat cached file paths before reading them","Treat the preview cache as disposable and re-render on any cache error"],"tags":["kitty","cache","filesystem","image-preview"],"backgroundTag":"stale-cache-read","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}