{"record":{"id":"d8dd89bfe9975186","repo":"kovidgoyal/kitty","slug":"missing-cached-data-for-frame-d","errorCode":null,"errorMessage":"missing cached data for frame: %d","messagePattern":"missing cached data for frame: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kittens/choose_files/image_preview.go","lineNumber":104,"sourceCode":"\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}\n\treturn images.ImageFromSerialized(m, frames)\n}\n\nfunc (p *ImagePreview) ensure_source_image() (err error) {\n\tif p.source_img != nil {\n\t\treturn\n\t}\n\tdefer func() {\n\t\tif err != nil {\n\t\t\tp.render_err = NewErrorPreview(err)","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kittens/choose_files/image_preview.go#L86-L122","documentation":"The cached metadata declares N frames but cached_data has no entry for key IMAGE_DATA_PREFIX+i for some frame i. The per-frame data files are keyed alongside the metadata, so a mismatch means the cache map is incomplete or frame keys were never populated.","triggerScenarios":"load_image iterates m.Frames and finds an empty string for cached_data[IMAGE_DATA_PREFIX+strconv.Itoa(i)], typically after the cache was only partially populated or frame count changed.","commonSituations":"Animation (GIF/APNG) preview where a previous render was interrupted mid-cache-write; cache key scheme changed between kitty versions.","solutions":["Invalidate the cache and trigger a fresh render of the image","Clear the preview cache directory","Report/check for a kitty version mismatch in cache key format"],"exampleFix":"// before\nif path == \"\" { return nil, fmt.Errorf(\"missing cached data for frame: %d\", i) }\n// after\nif path == \"\" {\n    invalidate_cache()\n    return nil, fmt.Errorf(\"missing cached data for frame %d, re-rendering\", i)\n}","handlingStrategy":"fallback","validationCode":"if len(m.Frames) > 0 && cached_data[IMAGE_DATA_PREFIX+\"0\"] == \"\" { /* incomplete cache, invalidate */ }","typeGuard":null,"tryCatchPattern":"On 'missing cached data for frame' errors, invalidate the cache entry and retry the render once without cache.","preventionTips":["Populate all frame keys before publishing metadata to the cache","Validate cache completeness (frame count vs keys) before use"],"tags":["kitty","cache","animation","image-preview"],"backgroundTag":"cache-miss","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}