{"record":{"id":"0e0ad951cbf2207b","repo":"kovidgoyal/kitty","slug":"failed-while-reading-from-file-s-with-error-s","errorCode":null,"errorMessage":"Failed while reading from file: %s with error: %s","messagePattern":"Failed while reading from file: (.+?) with error: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kitty/graphics.c","lineNumber":553,"sourceCode":"        fclose(fp);\n        return false;\n    }\n    while (!feof(fp)) {\n        if (capacity - pos < 1024) {\n            capacity *= 2;\n            unsigned char *new_buf = realloc(buf, capacity);\n            if (!new_buf) {\n                free(buf);\n                log_error(\"Out of memory reading PNG file at: %s\", path_for_error_messages);\n                fclose(fp);\n                return false;\n            }\n            buf = new_buf;\n        }\n        pos += fread(buf + pos, sizeof(char), capacity - pos, fp);\n        int saved_errno = errno;\n        if (ferror(fp) && saved_errno != EINTR) {\n            log_error(\"Failed while reading from file: %s with error: %s\", path_for_error_messages, strerror(saved_errno));\n            free(buf);\n            return false;\n        }\n    }\n    bool ret = png_from_data(buf, pos, path_for_error_messages, data, width, height, sz);\n    free(buf);\n    return ret;\n}\n\nbool\npng_path_to_bitmap(const char *path, uint8_t **data, unsigned int *width, unsigned int *height, size_t *sz) {\n    FILE *fp = fopen(path, \"r\");\n    if (fp == NULL) {\n        log_error(\"The PNG image: %s could not be opened with error: %s\", path, strerror(errno));\n        return false;\n    }\n    bool ret = png_from_file_pointer(fp, path, data, width, height, sz);\n    fclose(fp);","sourceCodeStart":535,"sourceCodeEnd":571,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/graphics.c#L535-L571","documentation":"fread set the stream error flag with an errno other than EINTR while reading the PNG file, so the read loop aborts, frees the buffer, and returns false. The strerror(errno) text (e.g. I/O error, EIO) identifies the underlying filesystem/device problem.","triggerScenarios":"Reading a PNG from a failing disk (EIO), an unplugged USB/network mount (EIO/ENODEV), a truncated NFS/FUSE file, or a file on a mount that disappears mid-read; EINTR reads are retried implicitly by being skipped from the error branch.","commonSituations":"background_image stored on a network share that drops; SD-card corruption on Raspberry Pi; VM shared-folder (vboxsf/prl_fs) I/O glitches; file deleted or truncated while kitty was starting.","solutions":["Check dmesg/storage health for I/O errors; remount the affected filesystem","Move the image to reliable local storage and update kitty.conf","Verify the file reads fully: cmp it against a copy, or md5sum twice","Re-save the PNG after confirming the source file is intact"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"import os\n\ndef readable_intact(path: str) -> bool:\n    try:\n        st = os.stat(path)\n        if not os.path.isfile(path) or st.st_size < 8:\n            return False\n        with open(path, 'rb') as f:\n            return f.read(8) == b'\\x89PNG\\r\\n\\x1a\\n'\n    except OSError:\n        return False","typeGuard":null,"tryCatchPattern":"// C: the code already skips EINTR; higher-level callers can retry the whole load once on transient EIO\nif (!png_path_to_bitmap(p, ...)) { if (errno == EIO) retry_once(); }","preventionTips":["Store kitty assets on reliable local disk, not flaky network mounts","Verify files with checksums after syncing configs","Check dmesg early when EIO appears — it usually precedes disk failure"],"tags":["kitty","png","io-error","filesystem","read-failure"],"backgroundTag":"file-read-io-error","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}