{"record":{"id":"4e974ae3f17fc2c6","repo":"kovidgoyal/kitty","slug":"failed-to-copy-data-to-new-disk-cache-file-during","errorCode":null,"errorMessage":"Failed to copy data to new disk cache file during defrag","messagePattern":"Failed to copy data to new disk cache file during defrag","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kitty/disk-cache.c","lineNumber":258,"sourceCode":"                fprintf(stderr, \"Failed to allocate space for keydup in defrag\\n\");\n                goto cleanup;\n            }\n        }\n    }\n    if (ftruncate(new_cache_file, total_data_size) != 0) {\n        perror(\"Failed to allocate space for new disk cache file during defrag\");\n        goto cleanup;\n    }\n    lseek(new_cache_file, 0, SEEK_SET);\n\n    mutex(unlock);\n    lock_released = true;\n\n    off_t current_pos = 0;\n    for (size_t i = 0; i < num_entries_to_defrag; i++) {\n        DefragEntry *e = defrag_entries + i;\n        if (!copy_between_files(self->cache_file_fd, new_cache_file, e->old_offset, e->data_sz, &fcb)) {\n            perror(\"Failed to copy data to new disk cache file during defrag\");\n            goto cleanup;\n        }\n        e->new_offset = current_pos;\n        current_pos += e->data_sz;\n    }\n    ok = true;\n\ncleanup:\n    if (lock_released) mutex(lock);\n    if (ok) {\n        cleanup_holes(&self->holes);\n        safe_close(self->cache_file_fd, __FILE__, __LINE__);\n        self->cache_file_fd = new_cache_file;\n        new_cache_file = -1;\n        for (size_t i = 0; i < num_entries_to_defrag; i++) {\n            DefragEntry *e = defrag_entries + i;\n            cache_map_itr i = vt_get(&self->map, e->key);\n            if (!vt_is_end(i)) i.data->val->pos_in_cache_file = e->new_offset;","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/disk-cache.c#L240-L276","documentation":"While copying scrollback cache entries from the old cache file to the new one during defrag, copy_between_files failed (sendfile/copy_file_range or read/write error). The defrag is abandoned mid-copy; existing entries in the old file remain valid and the partially built new file is discarded.","triggerScenarios":"defrag() after the ftruncate succeeded, when reading the source fd at old_offset fails (EIO, corrupted/truncated cache file after a crash) or writing to the new file fails (ENOSPC hit mid-copy).","commonSituations":"Power loss / kitty crash left a truncated cache file; disk filled between allocation and copy; failing disk returning EIO; cache on a filesystem where the copy syscall used is unsupported and falls back badly.","solutions":["Quit kitty and delete the disk-cache directory so it is rebuilt from scratch.","Check disk health and free space (df -i and df -h) on the cache filesystem.","Reproduce and report with kitty --debug if it persists across a rebuilt cache."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the cache dir on a healthy local disk.","Delete the cache dir after unclean shutdowns to avoid corrupted entries.","Watch dmesg for EIO on the cache device."],"tags":["disk-cache","io-error","defrag","kitty"],"backgroundTag":"cache-io-error","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}