kovidgoyal/kitty · error

%s does not exist

Error message

%s does not exist

What it means

For non-glob file specs, resolve_file_spec checks readability with unix.Access(R_OK). If the error is os.ErrNotExist, this specific 'does not exist' message naming the spec is returned (other access errors get a different message).

Source

Thrown at kittens/ssh/config.go:192

	}
	ans := os.ExpandEnv(paths_ctx.ExpandHome(spec))
	if !filepath.IsAbs(ans) {
		ans = paths_ctx.AbspathFromHome(ans)
	}
	if is_glob {
		files, err := doublestar.FilepathGlob(ans)
		if err != nil {
			return nil, fmt.Errorf("%s is not a valid glob pattern with error: %w", spec, err)
		}
		if len(files) == 0 {
			return nil, fmt.Errorf("%s matches no files", spec)
		}
		return files, nil
	}
	err := unix.Access(ans, unix.R_OK)
	if err != nil {
		if errors.Is(err, os.ErrNotExist) {
			return nil, fmt.Errorf("%s does not exist", spec)
		}
		return nil, fmt.Errorf("Cannot read from: %s with error: %w", spec, err)
	}
	return []string{ans}, nil
}

func get_arcname(loc, dest, home string) (arcname string) {
	if dest != "" {
		arcname = dest
	} else {
		arcname = filepath.Clean(loc)
		if strings.HasPrefix(arcname, home) {
			ra, err := filepath.Rel(home, arcname)
			if err == nil {
				arcname = ra
			}
		}
	}

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Check the absolute path after home expansion actually exists
  2. Fix relative vs absolute path confusion — specs are resolved via AbspathFromHome
  3. Create the missing file or remove the copy directive
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(paths_ctx.AbspathFromHome(spec)); errors.Is(err, os.ErrNotExist) { /* reject early */ }

Type guard

func fileExists(p string) bool { _, err := os.Stat(p); return err == nil }

Prevention

When it happens

Trigger: A copy: or env copy_from_local spec pointing at a path that does not exist on the local machine, after home-relative resolution.

Common situations: Relative paths being resolved against the wrong home (~ of the wrong user, sudo vs user), files not yet created, or deleted files referenced by stale config.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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