{"record":{"id":"19616b0366ca2bcc","repo":"kovidgoyal/kitty","slug":"failed-to-seek-in-disk-cache-file","errorCode":null,"errorMessage":"Failed to seek in disk cache file","messagePattern":"Failed to seek in disk cache file","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kitty/disk-cache.c","lineNumber":454,"sourceCode":"                find_hole_to_use(self, self->currently_writing.val.data_sz);\n                return true;\n            }\n            s->written_to_disk = true;\n            s->pos_in_cache_file = 0;\n            s->data_sz = 0;\n        }\n    }\n    return false;\n}\n\nstatic bool\nwrite_dirty_entry(DiskCache *self) {\n    size_t left = self->currently_writing.val.data_sz;\n    uint8_t *p = self->currently_writing.val.data;\n    if (self->currently_writing.val.pos_in_cache_file < 0) {\n        self->currently_writing.val.pos_in_cache_file = self->end_of_data_offset;\n        if (self->currently_writing.val.pos_in_cache_file < 0) {\n            perror(\"Failed to seek in disk cache file\");\n            return false;\n        }\n    }\n    off_t offset = self->currently_writing.val.pos_in_cache_file;\n    while (left > 0) {\n        ssize_t n = pwrite(self->cache_file_fd, p, left, offset);\n        if (n < 0) {\n            if (errno == EINTR || errno == EAGAIN) continue;\n            perror(\"Failed to write to disk-cache file\");\n            self->currently_writing.val.pos_in_cache_file = -1;\n            return false;\n        }\n        if (n == 0) {\n            fprintf(stderr, \"Failed to write to disk-cache file with zero return\\n\");\n            self->currently_writing.val.pos_in_cache_file = -1;\n            return false;\n        }\n        left -= n;","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/disk-cache.c#L436-L472","documentation":"write_dirty_entry computes the write offset as end_of_data_offset for a new cache entry and finds it negative, which should be impossible for a valid open cache file — perror then prints whatever errno happens to hold. It's an internal invariant failure in the disk-cache writer thread; the dirty entry is not persisted.","triggerScenarios":"The cache file fd's size query failed earlier (fstat/lseek returned -1) so end_of_data_offset stayed -1; happens on the background write_loop thread when flushing scrollback to a cache file that was closed, truncated externally, or never sized correctly.","commonSituations":"External deletion/truncation of kitty's cache file while kitty runs; a corrupted cache after a crash; racing close of the cache during shutdown.","solutions":["Quit kitty and delete the disk cache directory so it is recreated cleanly.","Ensure nothing (cleanup scripts, tmp cleaners like systemd-tmpfiles) deletes kitty cache files while kitty runs.","Update kitty — writer-thread offset handling has seen fixes."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never delete or truncate kitty's cache files while kitty runs.","Exclude kitty cache dirs from tmp cleaners (systemd-tmpfiles, bleachbit)."],"tags":["disk-cache","invariant","kitty"],"backgroundTag":"cache-corruption","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}