kovidgoyal/kitty · error
Failed to open %s for reading with error: %w
Error message
Failed to open %s for reading with error: %w
What it means
edit_in_kitty could not os.Open the target file path for reading. The underlying OS error is wrapped; typical causes are the file not existing or the process lacking read permission on it. The function aborts with exit code 1 before doing anything else.
Source
Thrown at tools/cmd/edit_in_kitty/main.go:182
return 1, tui.Canceled
}
ds := lp.DeathSignalName()
if ds != "" {
fmt.Print(abort_msg)
if kill_if_signaled {
lp.KillIfSignalled()
return
}
return 1, &tui.KilledBySignal{Msg: fmt.Sprint("Killed by signal: ", ds), SignalName: ds}
}
return
}
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)View on GitHub (pinned to 6d5d0c4406)
Solutions
- Confirm the path exists and is a regular file: ls -l <path>
- Use an absolute path to rule out CWD-relative resolution issues
- Fix permissions (or run with appropriate privileges) if the file exists but is unreadable
- If the file is being moved/deleted concurrently, re-resolve the path right before invoking the editor
Example fix
# before edit-in-kitty ./notes/../notes/old.txt # ENOENT # after edit-in-kitty "$(realpath old.txt)"
Defensive patterns
Strategy: validation
Validate before calling
// Resolve and check the file before calling the editor
abs, err := filepath.Abs(path)
if err != nil { return err }
if info, err := os.Stat(abs); err != nil || info.IsDir() {
return fmt.Errorf("not an editable regular file: %s", abs)
} Type guard
func isEditableFile(path string) bool {
info, err := os.Stat(path)
return err == nil && info.Mode().IsRegular()
} Try / catch
code, err := editInKitty(path, opts)
if err != nil && errors.Is(err, fs.ErrNotExist) {
// file vanished: re-prompt user or re-resolve path
} Prevention
- Pass absolute, symlink-resolved paths
- Re-stat the file immediately before launching the editor
- Handle ENOENT/EACCES distinctly so users get actionable messages
When it happens
Trigger: Calling edit_in_kitty with a path that doesn't exist, is a dangling symlink, is a directory, or resides where the user has no read permission (or with a stale NFS handle).
Common situations: Editing a file that was just deleted/moved by another process, race between picking a file in a file manager and opening it, wrong CWD-relative path, or running as a user without access to root-owned files.
Related errors
- %s is not readable and writeable
- failed to read the directory %s with error: %w
- Could not find any writable data directories. Make sure XDG_
- Could not find any writable portals directories. Make sure X
- Cannot read from: %s with error: %w
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/3d41bc992447c7e4.
Report an issue: GitHub.