apache/beam · error · ValueError
max_read_time_seconds must be > 0, got %r
Error message
max_read_time_seconds must be > 0, got %r
What it means
max_read_time_seconds caps the wall-clock duration of a single bundle read; it must be strictly positive. The constructor raises ValueError for zero or negative values, which would immediately terminate every bundle and make progress impossible.
Source
Thrown at sdks/python/apache_beam/io/unbounded_source.py:951
checked between records, so a reader that blocks inside ``advance()`` may
overrun it; ``max_records_per_bundle`` is the hard backstop.
The bundle self-checkpoints as soon as either cap is reached.
"""
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 = (View on GitHub (pinned to 12126d8942)
Solutions
- Pass a positive float, e.g. max_read_time_seconds=60.0
- Validate/clamp upstream: max_read_time_seconds=max(1e-3, value)
- For 'no limit' behavior, use a very large value instead of 0
Example fix
# before reader = Reader(source, max_read_time_seconds=0) # after reader = Reader(source, max_read_time_seconds=300.0)
Defensive patterns
Strategy: validation
Validate before calling
if float(max_read_time_seconds) <= 0:
raise ValueError('max_read_time_seconds must be > 0') Try / catch
try:
reader = Reader(source, max_read_time_seconds=t)
except ValueError:
reader = Reader(source, max_read_time_seconds=60.0) # safe default Prevention
- Guard duration computations against clock anomalies yielding <= 0
- Use large values, not 0, to mean 'effectively unlimited'
- Validate duration config at load time
When it happens
Trigger: Initializing the reader with max_read_time_seconds=0 or negative, typically from a mistyped config or a computation like (end - start) that evaluated to 0.
Common situations: Setting 0 intending 'no limit' (not valid here); unit tests passing 0 to 'disable' the cap; duration calculations in seconds returning 0 or negative due to clock issues.
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
- poll_interval 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/2e6dc30a09ae9f67.
Report an issue: GitHub.