kovidgoyal/kitty · error

%s is not readable and writeable

Error message

%s is not readable and writeable

What it means

Before handing the file to kitty, edit_in_kitty checks unix.Access(path, R_OK|W_OK) and aborts if the process can't both read and write it. This is a preflight check distinct from the earlier open: it explicitly requires write access too, since the editor will save the file back.

Source

Thrown at tools/cmd/edit_in_kitty/main.go:213

	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)
	}
	cwd, err := os.Getwd()
	if err != nil {
		return 1, fmt.Errorf("Failed to get the current working directory with error: %w", err)
	}
	add_encoded("cwd", cwd)
	for _, arg := range os.Args[2:] {
		add_encoded("a", arg)
	}
	add("file_inode", fmt.Sprintf("%d:%d:%d", s.Dev, s.Ino, s.Mtim.Nano()))
	add_encoded("file_data", utils.UnsafeBytesToString(file_data))
	fmt.Println("Waiting for editing to be completed, press Esc to abort...")
	write_data := func(data_type string, rdata []byte) (err error) {
		err = utils.AtomicWriteFile(path, bytes.NewReader(rdata), fs.FileMode(s.Mode).Perm())
		if err != nil {
			err = fmt.Errorf("Failed to write data to %s with error: %w", path, err)
		}
		return

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Fix permissions: chmod/chown as appropriate, or run under a user with write access
  2. Check for a read-only mount (mount -o remount,rw) or immutable attribute (lsattr; chattr -i)
  3. If the file shouldn't be modified, use a read-only pager instead of this editor
  4. Sudo only the edit step: sudo -e or run edit_in_kitty via sudo if policy allows

Example fix

# before
edit-in-kitty /etc/app/config.yaml   # EACCES: not writable
# after
sudo edit-in-kitty /etc/app/config.yaml
# or: chmod u+w /etc/app/config.yaml (if you own it)
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check read+write access exactly like the tool does
if err := unix.Access(path, unix.R_OK|unix.W_OK); err != nil {
    return fmt.Errorf("need read+write on %s — fix perms or use sudo", path)
}

Type guard

func isReadableWritable(path string) bool {
    return unix.Access(path, unix.R_OK|unix.W_OK) == nil
}

Try / catch

code, err := editInKitty(path, opts)
if err != nil && strings.Contains(err.Error(), "not readable and writeable") {
    // escalate deliberately rather than blanket-sudo
    exec.Command("sudo", os.Args[0], path).Run()
}

Prevention

When it happens

Trigger: Calling edit_in_kitty on a file the effective user can read but not write (root-owned file, no group/other write bit, read-only mount), or vice versa. Any non-nil Access result aborts.

Common situations: Editing system config files as a non-root user, files on read-only mounts (RO remount, immutable flag), or files owned by another user without write permission.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/bd017c5c28984c02. Report an issue: GitHub.