apache/beam · error · ValueError
poll_interval must be >= 0, got %r
Error message
poll_interval must be >= 0, got %r
What it means
poll_interval controls how long the reader sleeps between polls of the unbounded source; it must be non-negative. The constructor raises ValueError for negative values, since a negative sleep interval is meaningless and would break the polling loop.
Source
Thrown at sdks/python/apache_beam/io/unbounded_source.py:955
"""
def __init__(
self,
source: UnboundedSource,
poll_interval: float = _DEFAULT_POLL_INTERVAL_SECONDS,
max_records_per_bundle: int = _DEFAULT_MAX_RECORDS_PER_BUNDLE,
max_read_time_seconds: float = _DEFAULT_MAX_READ_TIME_SECONDS):
if not isinstance(source, UnboundedSource):
raise TypeError('source must be an UnboundedSource, got %r' % (source, ))
if max_records_per_bundle < 1:
raise ValueError(
'max_records_per_bundle must be >= 1, got %r' %
(max_records_per_bundle, ))
if max_read_time_seconds <= 0:
raise ValueError(
'max_read_time_seconds must be > 0, got %r' %
(max_read_time_seconds, ))
if poll_interval < 0:
raise ValueError(
'poll_interval must be >= 0, got %r' % (poll_interval, ))
super().__init__()
self._source = source
self._poll_interval = poll_interval
self._max_records_per_bundle = max_records_per_bundle
self._max_read_time_seconds = max_read_time_seconds
def expand(self, pbegin):
source = self._source
output_coder = source.default_output_coder()
# The source is the SDF element used to derive the initial restriction.
# process() reads from the restriction, so it does not use the element
# directly.
output = (
pbegin
| 'Create' >> core.Create([source])
| 'ReadUnbounded' >> core.ParDo(
_ReadFromUnboundedSourceDoFn(View on GitHub (pinned to 12126d8942)
Solutions
- Pass poll_interval >= 0 (0 means poll continuously without sleeping)
- Clamp the value: poll_interval=max(0.0, configured_value)
- Fix the config parsing or computation that produced the negative number
Example fix
# before reader = Reader(source, poll_interval=-1) # after reader = Reader(source, poll_interval=max(0.0, configured_interval))
Defensive patterns
Strategy: validation
Validate before calling
if float(poll_interval) < 0:
raise ValueError('poll_interval must be >= 0') Try / catch
try:
reader = Reader(source, poll_interval=p)
except ValueError:
reader = Reader(source, poll_interval=0.0) # poll without sleeping Prevention
- Use 0, not -1, as the neutral/default sentinel
- Clamp parsed intervals: max(0.0, value)
- Check sign handling in duration parsing code
When it happens
Trigger: Initializing the reader with poll_interval < 0, e.g. from a misparsed config ('-1'), or a computed interval that went negative.
Common situations: Using -1 as a 'default/disable' sentinel (use 0 instead); parsing a duration with a sign error; subtracting timestamps to derive the interval and getting a negative value.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- poll_interval_sec must be >= 15, got {poll_interval_sec}
- buffer_sec must be >= 0, got {buffer_sec}
- max_records_per_bundle must be >= 1, got %r
- max_read_time_seconds must be > 0, got %r
- MatchContinuously interval must be positive.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/bbd1918a11dd961c.
Report an issue: GitHub.