pika/pika · error · TypeError

{name} must be callable, but got {callback!r}

Error message

{name} must be callable, but got {callback!r}

What it means

Pika's I/O services require a genuinely callable object (function, lambda, or instance with __call__) for asynchronous completion callbacks. check_callback_arg() rejects anything non-callable, including None, strings, ints, and plain objects. The {name} placeholder identifies which parameter was wrong (e.g. on_done, protocol_factory).

Source

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

    errno.EWOULDBLOCK,
)

_LOGGER = logging.getLogger(__name__)

# Decorator that logs exceptions escaping from the decorated function
_log_exceptions = pika.diagnostic_utils.create_log_exception_decorator(_LOGGER)


def check_callback_arg(callback: Any, name: str) -> None:
    """
    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):

View on GitHub (pinned to 34a407b24f)

Solutions

  1. Pass an actual function, lambda, or bound-method reference (not its return value)
  2. Confirm the arg is required - these I/O-service callbacks do not accept None; do not omit them
  3. If you meant 'no callback', that path is not supported here; restructure to always supply one

Example fix

# before
nbio.connect_socket(sock, addr, on_done=None)  # TypeError

# after
def _on_done(error):
    ...
nbio.connect_socket(sock, addr, on_done=_on_done)
Defensive patterns

Strategy: type-guard

Validate before calling

def _ensure_callback(cb, name):
    if not callable(cb):
        raise TypeError(f'{name} must be callable, got {cb!r}')
    return cb

nbio.connect_socket(sock, addr, on_done=_ensure_callback(my_cb, 'on_done'))

Type guard

def is_callback(value) -> bool:
    return callable(value)

Try / catch

try:
    nbio.connect_socket(sock, addr, on_done=cb)
except TypeError as e:
    if 'must be callable' in str(e):
        raise  # or supply a real callback
    raise

Prevention

When it happens

Trigger: Passing None, a string, or a non-callable object to connect_socket(), create_streaming_connection(), or the _AsyncSocketConnector/_AsyncStreamConnector constructors as the on_done / protocol_factory argument.

Common situations: Forgetting the on_done argument and defaulting to None; passing a method name as a string instead of the bound method; passing the return value of a call instead of the function reference.

Related errors


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