{"record":{"id":"89e4e9ce1d2cce63","repo":"kovidgoyal/kitty","slug":"failed-to-read-cached-image-frame-d-data-w","errorCode":null,"errorMessage":"failed to read cached image frame %d data: %w","messagePattern":"failed to read cached image frame (.+?) data: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kittens/choose_files/image_preview.go","lineNumber":108,"sourceCode":"\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)\n\t\t}\n\t}()\n\tp.source_img, err = load_image(p.cached_data)\n\treturn","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kittens/choose_files/image_preview.go#L90-L126","documentation":"A frame data file whose path was stored in the cache could not be read from disk. Like error 260, this is a stale/invalid cache reference: the per-frame blob file was deleted or is unreadable while the metadata still references it.","triggerScenarios":"os.ReadFile(path) fails for a frame data file inside load_image's frame loop, called from RenderImagePreview/ensure_source_image.","commonSituations":"Cache cleanup jobs removing frame blobs; disk full or permission changes; container/sandbox environments with ephemeral temp dirs.","solutions":["Invalidate the cache entry and re-render from the source image","Verify the cache directory is persistent and writable for kitty's lifetime","Check disk space and permissions on the cache location"],"exampleFix":"// before\nd, e := os.ReadFile(path)\n// after\nd, e := os.ReadFile(path)\nif e != nil { invalidate_cache(); return nil, fmt.Errorf(\"frame %d cache unreadable, re-render: %w\", i, e) }","handlingStrategy":"fallback","validationCode":"for _, p := range framePaths { if _, err := os.Stat(p); err != nil { invalidate cache } }","typeGuard":null,"tryCatchPattern":"errors.Is(err, fs.ErrNotExist) || errors.Is(err, fs.ErrPermission) -> drop cache and re-render.","preventionTips":["Keep the cache directory dedicated to kitty and not subject to external cleanup","Check cache dir writability at kitten startup"],"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"}