python/cpython · error · TypeError
offset must be a non-negative integer (got {!r})
Error message
offset must be a non-negative integer (got {!r}) What it means
Raised by asyncio's sendfile parameter validation (_check_sendfile_params) when the `offset` argument to loop.sendfile() is not an int. `offset` is the byte position in the file to start sending from, and it must be an int (bools aside, anything else — float, string, None as a non-default — is rejected). This TypeError fires before any data is sent.
Source
Thrown at Lib/asyncio/base_events.py:1010
return total_sent
finally:
if total_sent > 0 and hasattr(file, 'seek'):
file.seek(offset + total_sent)
def _check_sendfile_params(self, sock, file, offset, count):
if 'b' not in getattr(file, 'mode', 'b'):
raise ValueError("file should be opened in binary mode")
if not sock.type == socket.SOCK_STREAM:
raise ValueError("only SOCK_STREAM type sockets are supported")
if count is not None:
if not isinstance(count, int):
raise TypeError(
"count must be a positive integer (got {!r})".format(count))
if count <= 0:
raise ValueError(
"count must be a positive integer (got {!r})".format(count))
if not isinstance(offset, int):
raise TypeError(
"offset must be a non-negative integer (got {!r})".format(
offset))
if offset < 0:
raise ValueError(
"offset must be a non-negative integer (got {!r})".format(
offset))
async def _connect_sock(self, exceptions, addr_info, local_addr_infos=None):
"""Create, bind and connect one socket."""
my_exceptions = []
exceptions.append(my_exceptions)
family, type_, proto, _, address = addr_info
sock = None
try:
try:
sock = socket.socket(family=family, type=type_, proto=proto)
sock.setblocking(False)
if local_addr_infos is not None:View on GitHub (pinned to bc6749cc3b)
Solutions
- Coerce offset to int at the call site: offset = int(offset).
- Use file.tell() (already an int) directly instead of recomputing a float offset.
- Validate offset >= 0 as well, since a negative int will raise the companion ValueError.
Example fix
// before await loop.sendfile(transport, f, offset=1024.0, count=None) # TypeError // after await loop.sendfile(transport, f, offset=1024, count=None)
Defensive patterns
Strategy: validation
Validate before calling
assert isinstance(offset, int) and not isinstance(offset, bool), 'offset must be an int'
Type guard
def is_valid_sendfile_offset(offset: object) -> bool:
return isinstance(offset, int) and not isinstance(offset, bool) Try / catch
try:
await loop.sendfile(transport, f, offset, count)
except TypeError as e:
if 'offset must be' not in str(e):
raise
offset = int(offset)
await loop.sendfile(transport, f, offset, count) Prevention
- Derive offset from file.tell() (always int) instead of recomputing it from float arithmetic.
- Sanitize offsets arriving from JSON — json numbers may parse as float.
- Wrap sendfile once in your own helper that coerces and validates offset/count.
When it happens
Trigger: Calling asyncio.sendfile(transport, file, offset) where offset is a float (e.g. 0.0), a string, or None. Note offset is positional and required to be an int; there is no 'None means default' escape hatch for it.
Common situations: Computing offset from file.tell() plus arithmetic that yields a float, or loading it from JSON/config where it arrives as a string or float.
Related errors
- sslcontext is expected to be an instance of ssl.SSLContext,
- d3-flame-graph library failed to load
- Unimplemented ioctl request
- profiling_trace: Placeholder pattern not found in {js_path.n
- server_hostname is only meaningful with ssl
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/f40cd87a664c206f.
Report an issue: GitHub.