kovidgoyal/kitty · error
Failed to read from %s with error: %w
Error message
Failed to read from %s with error: %w
What it means
io.ReadAll on the already-opened file failed. Since open and fstat succeeded, a read error here usually means the file became unreadable mid-read (I/O error, filesystem went away, permission changed via ACL) or the file grew/truncated concurrently producing inconsistent reads.
Source
Thrown at tools/cmd/edit_in_kitty/main.go:196
func edit_in_kitty(path string, opts *Options) (exit_code int, err error) {
read_file, err := os.Open(path)
if err != nil {
return 1, fmt.Errorf("Failed to open %s for reading with error: %w", path, err)
}
defer read_file.Close()
var s unix.Stat_t
err = unix.Fstat(int(read_file.Fd()), &s)
if err != nil {
return 1, fmt.Errorf("Failed to stat %s with error: %w", path, err)
}
if s.Size > int64(opts.MaxFileSize)*1024*1024 {
return 1, fmt.Errorf("File size %s is too large for performant editing", humanize.Bytes(uint64(s.Size)))
}
file_data, err := io.ReadAll(read_file)
if err != nil {
return 1, fmt.Errorf("Failed to read from %s with error: %w", path, err)
}
read_file.Close()
data := strings.Builder{}
data.Grow(len(file_data) * 4)
add := func(key, val string) {
if data.Len() > 0 {
data.WriteString(",")
}
data.WriteString(key)
data.WriteString("=")
data.WriteString(val)
}
add_encoded := func(key, val string) { add(key, encode(val)) }
if unix.Access(path, unix.R_OK|unix.W_OK) != nil {
return 1, fmt.Errorf("%s is not readable and writeable", path)
}View on GitHub (pinned to 6d5d0c4406)
Solutions
- Check dmesg/system logs for disk I/O errors; if present the storage is the problem
- Retry after remounting network filesystems; copy the file locally first
- If a rotating log is the target, edit a snapshot copy (cp first) instead of the live file
- Verify with: cat <file> > /dev/null to see if plain reads also fail
Example fix
# before edit-in-kitty /var/log/app/live.log # truncated mid-read by logrotate # after cp /var/log/app/live.log /tmp/edit.log && edit-in-kitty /tmp/edit.log
Defensive patterns
Strategy: retry
Validate before calling
// Verify the file reads cleanly before launching the editor
if f, err := os.Open(path); err == nil {
defer f.Close()
if _, err := io.Copy(io.Discard, io.LimitReader(f, 1<<20)); err != nil {
return fmt.Errorf("file unreadable (I/O error): %w", err)
}
} Try / catch
if err != nil && strings.Contains(err.Error(), "Failed to read from") {
time.Sleep(200 * time.Millisecond) // transient NFS/FUSE hiccup
// retry once; if it persists, copy the file locally and edit the copy
} Prevention
- Snapshot rotating logs before editing (cp then edit the copy)
- Copy files off flaky network mounts before opening them in the editor
When it happens
Trigger: edit_in_kitty opens the file, then during io.ReadAll the underlying storage returns EIO/ESTALE, the file is truncated by another writer, or a removable/network mount drops.
Common situations: Reading from failing disks (EIO), disconnected sshfs/NFS mounts, or editing a log file while logrotate rotates/truncates it.
Related errors
- Failed to open %s for reading with error: %w
- Failed to stat %s with error: %w
- %s is not readable and writeable
- Failed to get the current working directory with error: %w
- resolving base symlinks: %w
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/8a259e967448fb46.
Report an issue: GitHub.