pika/pika · error · TypeError

Paramter must be a file descriptor, but got {fd!r}

Error message

Paramter must be a file descriptor, but got {fd!r}

What it means

I/O services that watch file descriptors (add_reader/add_writer/remove_*) require an integer file descriptor. check_fd_arg() uses numbers.Integral, so floats, strings, socket objects, and None are rejected with TypeError. Note the source typo 'Paramter' is pre-existing; match it if grepping logs.

Source

Thrown at pika/adapters/utils/io_services_utils.py:67

    Raise TypeError if callback is not callable.

    :param callback: callback to check
    :param name: Name to include in exception text
    :raises TypeError:
    """
    if not callable(callback):
        raise TypeError(f'{name} must be callable, but got {callback!r}')


def check_fd_arg(fd: int) -> None:
    """
    Raise TypeError if file descriptor is not an integer.

    :param fd: file descriptor
    :raises TypeError:
    """
    if not isinstance(fd, numbers.Integral):
        raise TypeError(f'Paramter must be a file descriptor, but got {fd!r}')


def _retry_on_sigint(func):
    """Function decorator for retrying on SIGINT."""

    @functools.wraps(func)
    def retry_sigint_wrap(*args, **kwargs):
        """Wrapper for decorated function."""
        while True:
            try:
                return func(*args, **kwargs)
            except pika._utils.SOCKET_ERROR as error:
                if error.errno == errno.EINTR:
                    continue
                raise

    return retry_sigint_wrap

View on GitHub (pinned to 34a407b24f)

Solutions

  1. Call sock.fileno() to obtain the integer descriptor before passing it
  2. Ensure you pass an int, not a socket object or float
  3. Use pika's public connection APIs which handle fd extraction internally

Example fix

# before
nbio.add_reader(my_socket, callback)  # TypeError

# after
nbio.add_reader(my_socket.fileno(), callback)
Defensive patterns

Strategy: type-guard

Validate before calling

import numbers
def as_fd(value) -> int:
    if not isinstance(value, numbers.Integral):
        raise TypeError(f'Expected int fd, got {value!r}')
    return int(value)

nbio.add_reader(as_fd(sock.fileno()), cb)

Type guard

import numbers
def is_file_descriptor(value) -> bool:
    return isinstance(value, numbers.Integral)

Try / catch

try:
    nbio.add_reader(fd, cb)
except TypeError as e:
    if 'file descriptor' in str(e):
        nbio.add_reader(sock.fileno(), cb)
    else:
        raise

Prevention

When it happens

Trigger: Passing a socket object instead of sock.fileno(); passing a float fd; passing a stringified fd. Happens when calling low-level nbio file-descriptor registration methods directly (typically from a custom adapter).

Common situations: Confusing a socket object with its integer fd; calling private nbio APIs from bespoke adapter code; off-by-one producing a float.

Related errors


AI-assisted analysis of pika/pika@34a407b24f (2026-08-07). Data as JSON: /api/errors/8fa5c8da9eb87b51. Report an issue: GitHub.