{"record":{"id":"e78fc4b43937abb7","repo":"kovidgoyal/kitty","slug":"failed-to-stat-s-with-error-w-e78fc4","errorCode":null,"errorMessage":"Failed to stat %s with error: %w","messagePattern":"Failed to stat (.+?) with error: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tools/cmd/edit_in_kitty/main.go","lineNumber":188,"sourceCode":"\t\tif kill_if_signaled {\n\t\t\tlp.KillIfSignalled()\n\t\t\treturn\n\t\t}\n\t\treturn 1, &tui.KilledBySignal{Msg: fmt.Sprint(\"Killed by signal: \", ds), SignalName: ds}\n\t}\n\treturn\n}\n\nfunc edit_in_kitty(path string, opts *Options) (exit_code int, err error) {\n\tread_file, err := os.Open(path)\n\tif err != nil {\n\t\treturn 1, fmt.Errorf(\"Failed to open %s for reading with error: %w\", path, err)\n\t}\n\tdefer read_file.Close()\n\tvar s unix.Stat_t\n\terr = unix.Fstat(int(read_file.Fd()), &s)\n\tif err != nil {\n\t\treturn 1, fmt.Errorf(\"Failed to stat %s with error: %w\", path, err)\n\t}\n\tif s.Size > int64(opts.MaxFileSize)*1024*1024 {\n\t\treturn 1, fmt.Errorf(\"File size %s is too large for performant editing\", humanize.Bytes(uint64(s.Size)))\n\t}\n\n\tfile_data, err := io.ReadAll(read_file)\n\tif err != nil {\n\t\treturn 1, fmt.Errorf(\"Failed to read from %s with error: %w\", path, err)\n\t}\n\tread_file.Close()\n\tdata := strings.Builder{}\n\tdata.Grow(len(file_data) * 4)\n\n\tadd := func(key, val string) {\n\t\tif data.Len() > 0 {\n\t\t\tdata.WriteString(\",\")\n\t\t}\n\t\tdata.WriteString(key)","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/tools/cmd/edit_in_kitty/main.go#L170-L206","documentation":"After successfully opening the file, unix.Fstat on its descriptor failed. This is rare because the fd is already open — it usually indicates the filesystem can't stat the open inode (broken NFS/FUSE mount, fd closed underneath) or an fd inheritance edge case rather than a bad path.","triggerScenarios":"Calling edit_in_kitty on a file whose backing filesystem goes away between open and fstat (network filesystem disconnect, FUSE daemon crash), or on a pseudo-file where fstat returns an error despite open succeeding.","commonSituations":"Editing files on stale NFS mounts, sshfs/FUSE mounts that dropped, or special files under /proc or /sys with odd stat semantics.","solutions":["Retry after remounting/reconnecting the network or FUSE filesystem","Check mount health: mount | grep <fs>, df <path>","If it reproduces on a specific file, stat it manually: stat <path> to see the kernel error","Avoid editing files on flaky network mounts; copy locally first"],"exampleFix":"# before\nedit-in-kitty /mnt/nfs-shared/big.txt   # ESTALE\n# after\ncp /mnt/nfs-shared/big.txt /tmp/ && edit-in-kitty /tmp/big.txt","handlingStrategy":"try-catch","validationCode":"// Check mount health before editing files on network filesystems\nif out, err := exec.Command(\"findmnt\", \"-n\", \"-o\", \"TARGET\", path).Output(); err != nil {\n    return fmt.Errorf(\"path %s has no healthy mount\", path)\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"Failed to stat\") {\n    // open succeeded but inode gone: retry once, then copy file locally\n}","preventionTips":["Prefer local copies of files on NFS/FUSE before editing","Detect ESTALE/EIO in wrapped errors and surface a remount hint"],"tags":["filesystem","fstat","nfs","fuse","go"],"backgroundTag":"file-stat-failed","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}