python/cpython · warning · TypeError
{future!r} object does not appear to be compatible with asyn
Error message
{future!r} object does not appear to be compatible with asyncio.Future What it means
The internal graph builder used by asyncio's future debugging (e.g. when a future is garbage-collected while never-awaited warnings are emitted) requires an exact asyncio.Future. A Task-like or duck-typed object lacking the Future interface raises this TypeError because call-graph introspection depends on Future internals (get_coro, _asyncio_awaited_by).
Source
Thrown at Lib/asyncio/graph.py:46
@dataclasses.dataclass(frozen=True, slots=True)
class FrameCallGraphEntry:
frame: types.FrameType
@dataclasses.dataclass(frozen=True, slots=True)
class FutureCallGraph:
future: futures.Future
call_stack: tuple["FrameCallGraphEntry", ...]
awaited_by: tuple["FutureCallGraph", ...]
def _build_graph_for_future(
future: futures.Future,
*,
limit: int | None = None,
) -> FutureCallGraph:
if not isinstance(future, futures.Future):
raise TypeError(
f"{future!r} object does not appear to be compatible "
f"with asyncio.Future"
)
coro = None
if get_coro := getattr(future, 'get_coro', None):
coro = get_coro() if limit != 0 else None
st: list[FrameCallGraphEntry] = []
awaited_by: list[FutureCallGraph] = []
while coro is not None:
if hasattr(coro, 'cr_await'):
# A native coroutine or duck-type compatible iterator
st.append(FrameCallGraphEntry(coro.cr_frame))
coro = coro.cr_await
elif hasattr(coro, 'ag_await'):
# A native async generator or duck-type compatible iteratorView on GitHub (pinned to bc6749cc3b)
Solutions
- Pass only real asyncio.Future/Task instances to capture_call_graph()
- Guard with isinstance(x, asyncio.Future) before introspection
- For concurrent futures, wrap with asyncio.wrap_future() first
Example fix
# before
asyncio.graph.capture_call_graph(future=my_custom_awaitable) # TypeError
# after
if isinstance(fut, asyncio.Future):
graph = asyncio.graph.capture_call_graph(future=fut) Defensive patterns
Strategy: type-guard
Validate before calling
import asyncio
if not isinstance(fut, asyncio.Future):
# cannot introspect; skip graph capture Type guard
def is_asyncio_future(obj) -> bool:
return isinstance(obj, asyncio.Future) Prevention
- Only pass genuine asyncio.Future/Task to graph introspection
- Wrap concurrent futures with wrap_future() first
- Use Mock(spec=asyncio.Future) in tests
When it happens
Trigger: Calling asyncio.graph._build_graph_for_future (or capture_call_graph with an explicit future) with a custom awaitable, a concurrent.futures.Future, or a third-party task implementation.
Common situations: Debug tooling or error-reporting libraries that introspect 'never awaited' futures; passing a trio-style nursery object; mocks in tests.
Related errors
- A future is required for source argument
- A future is required for destination argument
- Not implemented
- Unknown thread safety level {level!r} for {name!r}. Valid le
- expected AST, got %r
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/182ebfce04807091.
Report an issue: GitHub.