kovidgoyal/kitty · warning · ValueError

Failed to find cwd of process with pid: {pid}

Error message

Failed to find cwd of process with pid: {pid}

What it means

On Linux, cwd_of_process shells out to `pwdx <pid>` and raises ValueError when pwdx exits non-zero, i.e. the process's working directory could not be determined (process gone, permission denied, or kernel restriction).

Source

Thrown at kitty/child.py:86

            for p in pids:
                with suppress(Exception):
                    total += _memory_of_process(p)
            return total
        return -1
else:

    def cmdline_of_pid(pid: int) -> list[str]:
        with open(f'/proc/{pid}/cmdline', 'rb') as f:
            return list(filter(None, f.read().decode('utf-8').split('\0')))

    if is_freebsd:

        def cwd_of_process(pid: int) -> str:
            import subprocess

            cp = subprocess.run(['pwdx', str(pid)], capture_output=True)
            if cp.returncode != 0:
                raise ValueError(f'Failed to find cwd of process with pid: {pid}')
            ans = cp.stdout.decode('utf-8', 'replace').split()[1]
            return os.path.realpath(ans, strict=True)
    else:

        def cwd_of_process(pid: int) -> str:
            # We use realpath instead of readlink to match macOS behavior where
            # the underlying OS API returns real paths.
            ans = f'/proc/{pid}/cwd'
            return os.path.realpath(ans, strict=True)

    def _environ_of_process(pid: int) -> str:
        with open(f'/proc/{pid}/environ', 'rb') as f:
            return f.read().decode('utf-8')

    def process_group_map() -> DefaultDict[int, list[int]]:
        ans: DefaultDict[int, list[int]] = defaultdict(list)
        for x in os.listdir('/proc'):
            try:

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Ensure pwdx is installed (part of procps)
  2. Retry with a live pid; check the process still exists before calling
  3. Run with sufficient permissions to inspect the target process
  4. Catch ValueError and fall back to $HOME or the parent's cwd

Example fix

# before
cwd = cwd_of_process(pid)
# after
try:
    cwd = cwd_of_process(pid)
except (ValueError, FileNotFoundError):
    cwd = os.path.expanduser('~')
Defensive patterns

Strategy: fallback

Validate before calling

import os
pid_alive = os.path.exists(f'/proc/{pid}')
cwd = cwd_of_process(pid) if pid_alive else fallback_dir

Try / catch

try:
    cwd = cwd_of_process(pid)
except ValueError:
    cwd = os.path.expanduser('~')

Prevention

When it happens

Trigger: Calling cwd_of_process for a pid that has exited, a zombie, a process owned by another user (pwdx fails without permission), or on systems where hidepid/ptrace restrictions apply.

Common situations: kitty resolving the cwd of the shell/child process for window inheritance or `neighbor` semantics after the child died, or in restricted multi-user environments lacking pwdx or permissions.

Related errors


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