pika/pika · error · TypeError
on_done arg must be callable, but got {on_done!r}
Error message
on_done arg must be callable, but got {on_done!r} What it means
`_AsyncioIOServicesAdapter._schedule_and_wrap_in_io_ref` wraps an asyncio future/coroutine and registers an `on_done` callback for completion. The guard rejects a non-callable `on_done` immediately so the future is never left without a completion handler. This method is reached through the public `getaddrinfo` method (which takes `on_done`) and through streaming-connection setup.
Source
Thrown at pika/adapters/asyncio_connection.py:259
:param fd: File descriptor
"""
LOGGER.debug('remove_writer(%s)', fd)
return self._loop.remove_writer(fd)
def _schedule_and_wrap_in_io_ref(
self, coro: Awaitable[Any],
on_done: Callable[[base_connection.BaseConnection | BaseException],
None]
) -> _AsyncioIOReference:
"""
Schedule the coroutine to run and return _AsyncioIOReference.
:param coro: Coroutine to schedule.
:param on_done: User callback that takes the completion result or exception as its only arg.
It will not be called if the operation was cancelled.
"""
if not callable(on_done):
raise TypeError(
f'on_done arg must be callable, but got {on_done!r}')
return _AsyncioIOReference(asyncio.ensure_future(coro, loop=self._loop),
on_done)
class _TimerHandle(nbio_interface.AbstractTimerReference):
"""This module's adaptation of `nbio_interface.AbstractTimerReference`."""
def __init__(self, handle: asyncio.Handle) -> None:
"""
:param handle:
"""
self._handle: asyncio.Handle | None = handle
@override
def cancel(self) -> None:View on GitHub (pinned to 34a407b24f)
Solutions
- Pass a real callable (function/lambda/bound method) as `on_done`.
- If you don't need completion notification, pass a no-op: `on_done=lambda *_: None`.
Example fix
# before nbio.getaddrinfo(host, port, on_done=None) # after nbio.getaddrinfo(host, port, on_done=lambda addrinfo_or_exc: None)
Defensive patterns
Strategy: type-guard
Validate before calling
if not callable(on_done):
raise TypeError('on_done must be callable')
nbio.getaddrinfo(host, port, on_done=on_done) Type guard
def is_callable_zero_arg(fn) -> bool:
return callable(fn) Prevention
- Pass lambdas or bound methods for completion callbacks.
- Use a no-op (lambda *_: None) when you don't need the result.
- Avoid extending _AsyncioIOServicesAdapter unless necessary.
When it happens
Trigger: Calling `nbio.getaddrinfo(host, port, on_done=<non-callable>)` on the asyncio nbio adapter, or subclassing `_AsyncioIOServicesAdapter` / implementing a custom transport that forwards a None or non-callable completion callback into this method.
Common situations: Implementing a custom `AbstractStreamTransport` or `AbstractFileDescriptorIOServices` and forgetting to pass the completion callback, or passing a string attribute name or a result object instead of a function for `on_done`.
Related errors
- Expected pika.connection.Parameters instance, but got None i
- callback must be a callable, but got {callback!r}
- exactly one of on_message_callback/alternate_event_sink must
- callback must be a callable, but got {callback!r}
- callback should be None or a callable
AI-assisted analysis of pika/pika@34a407b24f (2026-08-07).
Data as JSON: /api/errors/8a5ee3b8237951d4.
Report an issue: GitHub.