python/cpython · error · ValueError

Limit cannot be <= 0

Error message

Limit cannot be <= 0

What it means

ValueError raised by StreamReader.__init__ when the limit argument is zero or negative. The limit is both the readline/readuntil separator length bound and half the flow-control buffer size, so a non-positive value is meaningless and rejected immediately at construction.

Source

Thrown at Lib/asyncio/streams.py:420

    def __del__(self, warnings=warnings):
        if not self._transport.is_closing():
            if self._loop.is_closed():
                warnings.warn("loop is closed", ResourceWarning)
            else:
                self.close()
                warnings.warn(f"unclosed {self!r}", ResourceWarning)

class StreamReader:

    _source_traceback = None

    def __init__(self, limit=_DEFAULT_LIMIT, loop=None):
        # The line length limit is  a security feature;
        # it also doubles as half the buffer limit.

        if limit <= 0:
            raise ValueError('Limit cannot be <= 0')

        self._limit = limit
        if loop is None:
            self._loop = events.get_event_loop()
        else:
            self._loop = loop
        self._buffer = bytearray()
        self._eof = False    # Whether we're done.
        self._waiter = None  # A future used by _wait_for_data()
        self._exception = None
        self._transport = None
        self._paused = False
        if self._loop.get_debug():
            self._source_traceback = format_helpers.extract_stack(
                sys._getframe(1))

    def __repr__(self):
        info = ['StreamReader']

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Pass a positive limit (default is 64 KiB, _DEFAULT_LIMIT); choose it deliberately given readline/readuntil semantics
  2. Validate/derive config values at startup: limit = max(1, configured) only if a sane default is intended, otherwise fail fast with a clear config error
  3. If you meant 'no line limit', pick a large explicit value rather than 0 — the parameter is not an on/off switch

Example fix

// before
reader, writer = await asyncio.open_connection(host, port, limit=cfg.max_line_bytes)  # cfg value 0

// after
if cfg.max_line_bytes <= 0:
    raise ValueError(f'max_line_bytes must be > 0, got {cfg.max_line_bytes}')
reader, writer = await asyncio.open_connection(host, port, limit=cfg.max_line_bytes)
Defensive patterns

Strategy: validation

Validate before calling

def checked_limit(value: int) -> int:
    if not isinstance(value, int) or value <= 0:
        raise ValueError(f'stream limit must be a positive int, got {value!r}')
    return value

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: StreamReader(limit=0), StreamReader(limit=-1), or asyncio.open_connection/start_server(..., limit=n) with n <= 0; typically the value comes from a config value, CLI flag, or arithmetic that evaluated to zero.

Common situations: A 'max line length' setting defaulting to 0 meaning 'unset'; computing limit as a difference or percentage that collapses to 0; passing a buffer-size knob meant for something else into the streams limit parameter.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/620e4c99bd881b6d. Report an issue: GitHub.