{"record":{"id":"afa2e9f92bff11c5","repo":"kovidgoyal/kitty","slug":"poll-on-talk-fds-failed","errorCode":null,"errorMessage":"poll() on talk fds failed","messagePattern":"poll\\(\\) on talk fds failed","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kitty/child-monitor.c","lineNumber":2271,"sourceCode":"            for (size_t k = 0; k < talk_data.num_peers; k++) {\n                Peer *p = talk_data.peers + k;\n                if (p->fd_array_idx) {\n                    if (fds[p->fd_array_idx].revents & POLLIN) read_from_peer(self, p);\n                    if (fds[p->fd_array_idx].revents & POLLOUT) write_to_peer(p);\n                    if (fds[p->fd_array_idx].revents & POLLHUP) {\n                        // try to read and write nonetheless these functions will set the failed flags.\n                        if (!p->read.finished) read_from_peer(self, p);\n                        if (p->write.used) write_to_peer(p);\n                    }\n                    if (fds[p->fd_array_idx].revents & POLLNVAL) {\n                        p->read.finished = true;\n                        p->write.failed = true;\n                        p->write.used = 0;\n                    }\n                }\n            }\n        } else if (ret < 0) {\n            if (errno != EAGAIN && errno != EINTR) perror(\"poll() on talk fds failed\");\n        }\n    }\nend:\n    free_loop_data(&talk_data.loop_data);\n    for (size_t i = 0; i < talk_data.num_peers; i++) free_peer(talk_data.peers + i);\n    free(talk_data.peers);\n    return 0;\n}\n\nstatic void\nsend_response_to_peer(id_type peer_id, const char *msg, size_t msg_sz, bool is_async_response) {\n    bool wakeup = false;\n    talk_mutex(lock);\n    for (size_t i = 0; i < talk_data.num_peers; i++) {\n        Peer *peer = talk_data.peers + i;\n        if (peer->id == peer_id) {\n            peer->waiting_for_async_response = is_async_response;\n            if (peer->num_of_unresponded_messages_sent_to_main_thread) peer->num_of_unresponded_messages_sent_to_main_thread--;","sourceCodeStart":2253,"sourceCodeEnd":2289,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/child-monitor.c#L2253-L2289","documentation":"perror emitted when poll() over the 'talk' file descriptors (kitty's internal peer/remote-control IPC sockets) returns a negative value that is not EAGAIN or EINTR. This means the multiplexed IPC event loop in child-monitor.c could not wait on its sockets, usually due to a bad/stale fd or EBADF/EFAULT after a peer died. kitty logs it and continues; it indicates IPC plumbing trouble rather than a terminal failure.","triggerScenarios":"poll() returning -1 with errno such as EBADF (a closed talk fd still in the poll set), EFAULT (fds array out of reach), or ENOMEM, while running kitty with remote control (--listen-on), single-instance sockets, or peer kittens talking to the main process.","commonSituations":"A peer kitten or socket client crashes mid-connection leaving a stale fd; fd exhaustion on systems with many kittens/windows; bugs in older kitty versions where dead peer fds were not removed from the poll set.","solutions":["Check dmesg/system logs for fd exhaustion; raise ulimit -n if the process is near its limit.","Update kitty — stale-peer fd handling in the talk loop has been fixed in newer releases.","Reproduce with KITTY_DEBUG / --debug-ipc if available and report the errno value printed after the message.","If tied to a kitten, restart the kitten rather than the whole kitty session; the main loop recovers."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep peer kittens and the kitty main binary on the same version.","Avoid spawning hundreds of concurrent peer kittens that die abruptly.","Monitor fd usage (ls /proc/$(pidof kitty)/fd | wc -l) in automation."],"tags":["ipc","poll","kitty","errno"],"backgroundTag":"ipc-poll-fd-error","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}