kovidgoyal/kitty · error · TypeError

'size' must be a non-negative integer

Error message

'size' must be a non-negative integer

What it means

SharedMemory.__init__ validates its arguments: a negative size is rejected immediately with TypeError("'size' must be a non-negative integer"). A zero size is also rejected later ('size' must be > 0) unless an existing name is given, since a new mapping must have nonzero size.

Source

Thrown at kitty/shm.py:63

    _mmap: mmap.mmap | None = None
    _size: int = 0
    size_fmt = '!I'
    num_bytes_for_size = struct.calcsize(size_fmt)

    def __init__(
        self,
        name: str = '',
        size: int = 0,
        readonly: bool = False,
        mode: int = stat.S_IREAD | stat.S_IWRITE,
        prefix: str = 'kitty-',
        unlink_on_exit: bool = False,
        ignore_close_failure: bool = False,
    ):
        self.unlink_on_exit = unlink_on_exit
        self.ignore_close_failure = ignore_close_failure
        if size < 0:
            raise TypeError("'size' must be a non-negative integer")
        if size and name:
            raise TypeError('Cannot specify both name and size')
        if not name:
            flags = os.O_CREAT | os.O_EXCL
            if not size:
                raise TypeError("'size' must be > 0")
        else:
            flags = 0
        flags |= os.O_RDONLY if readonly else os.O_RDWR

        tries = 30
        while not name and tries > 0:
            tries -= 1
            q = make_filename(prefix)
            try:
                self._fd = shm_open(q, flags, mode)
                name = q
            except FileExistsError:

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Ensure size is a positive int before constructing: guard `size = max(0, len(payload))` and skip/short-circuit when 0
  2. Pass name= only when attaching to an existing shm, never together with a positive size
  3. Validate with isinstance(size, int) and size > 0 at the API boundary

Example fix

# before
shm = SharedMemory(size=len(payload))  # payload may be empty
# after
if not payload:
    return
shm = SharedMemory(size=len(payload))
Defensive patterns

Strategy: type-guard

Validate before calling

def valid_shm_size(size: object) -> bool:
    return isinstance(size, int) and not isinstance(size, bool) and size > 0

Type guard

def is_valid_shm_size(size: unknown) -> size is int:
    return isinstance(size, int) and not isinstance(size, bool) and size > 0

Try / catch

try:
    shm = SharedMemory(size=size)
except TypeError as e:
    raise ValueError(f'bad SharedMemory size: {size!r}') from e

Prevention

When it happens

Trigger: Calling SharedMemory(size=-1) (negative size), or SharedMemory(size=0) without name (new object must have positive size); commonly from passing an unvalidated or computed size that can be 0/negative, e.g. len(data) with empty data.

Common situations: Allocating shm sized from user input or empty payloads; refactoring code where size defaults to 0 and previously a name was always passed.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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