aio-libs/aiohttp · error · RuntimeError
Called while some coroutine is waiting for incoming data.
Error message
Called while some coroutine is waiting for incoming data.
What it means
Raised by StreamReader.read_nowait when an async reader is currently blocked in _wait (self._waiter is pending). read_nowait is a synchronous drain that bypasses the waiter protocol; calling it concurrently with an awaited read would steal the awaited data. aiohttp refuses with RuntimeError to preserve the read-coroutine contract.
Source
Thrown at aiohttp/streams.py:532
block = await self.read(n)
if not block:
partial = b"".join(blocks)
raise asyncio.IncompleteReadError(partial, len(partial) + n)
blocks.append(block)
n -= len(block)
return b"".join(blocks)
def read_nowait(self, n: int = -1) -> bytes:
# default was changed to be consistent with .read(-1)
#
# I believe the most users don't know about the method and
# they are not affected.
if self._exception is not None:
raise self._exception
if self._waiter and not self._waiter.done():
raise RuntimeError(
"Called while some coroutine is waiting for incoming data."
)
chunk = self._read_nowait(n)
if chunk and (cb := self._on_chunk_received) is not None:
# read_nowait is sync but the hook is async; schedule it so the
# observability event still fires.
# TODO: Save and await this task.
asyncio.create_task(cb(chunk)) # type: ignore[unused-awaitable]
return chunk
def _read_nowait_chunk(self, n: int) -> bytes:
first_buffer = self._buffer[0]
offset = self._buffer_offset
if n != -1 and len(first_buffer) - offset > n:
data = first_buffer[offset : offset + n]
self._buffer_offset += n
View on GitHub (pinned to c0ef574e29)
Solutions
- Do not mix read_nowait with awaited reads on the same stream — pick one consumer model.
- Before read_nowait, check `if request.content._waiter and not request.content._waiter.done(): ...` (or just avoid read_nowait).
- Use readany() (async) instead of read_nowait for non-blocking-style reads.
- Ensure no background await is in flight when you call read_nowait.
Example fix
// before # in a sync callback, while handler awaits request.read(): peek = request.content.read_nowait() # RuntimeError // after # schedule the peek as async instead: peek = await request.content.readany()
Defensive patterns
Strategy: validation
Validate before calling
def safe_read_nowait(stream, n=-1):
waiter = getattr(stream, '_waiter', None)
if waiter is not None and not waiter.done():
raise RuntimeError('cannot read_nowait while async read is pending')
return stream.read_nowait(n) Try / catch
try:
chunk = stream.read_nowait()
except RuntimeError as e:
if 'waiting for incoming data' in str(e):
# fall back to async read
chunk = await stream.readany()
else:
raise Prevention
- Never mix sync read_nowait with awaited reads on the same stream.
- Use readany() for non-blocking-style reads.
- Centralize all stream access behind one async consumer.
When it happens
Trigger: Calling request.content.read_nowait() from sync code (e.g. a sync callback, __del__, signal handler) while an async task is awaiting request.content.read(...); mixing read_nowait with awaited reads for performance without coordination.
Common situations: Sync middleware/callback that peeks at the buffer while the handler is reading; instrumentation that drains for metrics; incorrect port of a sync API onto an async stream.
Related errors
- %s() called while another coroutine is already waiting for i
- Cannot write to closing transport
- Concurrent call to receive() is not allowed
- Called begin_http_chunk_receiving when some data was already
- Called end_chunk_receiving without calling begin_chunk_recei
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/46bcf1a0ad71e614.json.
Report an issue: GitHub.