apache/beam · error · ValueError

'timeout' must be a non-negative number

Error message

'timeout' must be a non-negative number

What it means

ByteLimitedQueue.put validates that its timeout, when provided, is not negative. A negative timeout is meaningless for blocking semantics, so Beam raises ValueError immediately before touching the queue. The docstring explicitly documents ValueError for negative timeout.

Solutions

  1. Clamp the timeout before calling: timeout = max(0, timeout).
  2. Pass timeout=None for infinite blocking if no deadline is intended.
  3. Fix the deadline arithmetic that produced the negative value.
  4. Validate user/config-supplied timeouts at load time.

Example fix

// before
q.put(item, item_bytes=n, timeout=deadline - time.time())
// after
q.put(item, item_bytes=n, timeout=max(0, deadline - time.time()))
Defensive patterns

Strategy: validation

Validate before calling

if timeout is not None and timeout < 0:
    raise ValueError('timeout must be >= 0 or None')

Try / catch

try:
    q.put(item, item_bytes=n, timeout=t)
except ValueError:
    q.put(item, item_bytes=n, timeout=None)

Prevention

When it happens

Trigger: Calling byte_queue.put(item, item_bytes=..., block=True, timeout=-1) or passing a computed timeout that underflowed to a negative value.

Common situations: Computing a deadline as (deadline - now) after the deadline has passed; config files with negative timeout values; mixing units (ms vs seconds) producing negative remainders.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/bd0150c5c9043fb3. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/utils/byte_limited_queue.py:80

    """Put an item into the queue.

    If the queue is full, block until a free slot is available, unless `block`
    is false or a timeout occurs.

    Args:
      item: The item to put into the queue.
      item_bytes: The size of the item.
      block: If True, block until space is available. If False, raise queue.Full
        immediately if the queue is full.
      timeout: If block is True, wait for at most `timeout` seconds. If None,
        block indefinitely.

    Raises:
      ValueError: If timeout or item_bytes is negative.
      queue.Full: If the queue is full and block is False or the timeout occurs.
    """
    if timeout is not None and timeout < 0:
      raise ValueError("'timeout' must be a non-negative number")
    if item_bytes < 0:
      raise ValueError("'item_bytes' must be a non-negative number")

    with self._mutex:
      if not self._waiting_writers and self._can_fit(item_bytes):
        self._queue.append((item, item_bytes))
        self._byte_size += item_bytes
        self._not_empty.notify()
        return

      if not block:
        raise queue.Full

      # Reuse or create a condition
      my_cond = (
          self._condition_pool.pop()
          if self._condition_pool else threading.Condition(self._mutex))

View on GitHub (pinned to 12126d8942)