{"record":{"id":"ff70bb206d5d3dd7","repo":"apache/beam","slug":"stop-offset-must-be-a-number-received-r","errorCode":null,"errorMessage":"stop_offset must be a number. Received: %r","messagePattern":"stop_offset must be a number\\. Received: %r","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/filebasedsource.py","lineNumber":256,"sourceCode":"  return compression_type == CompressionTypes.UNCOMPRESSED\n\n\nclass _SingleFileSource(iobase.BoundedSource):\n  \"\"\"Denotes a source for a specific file type.\"\"\"\n  def __init__(\n      self,\n      file_based_source,\n      file_name,\n      start_offset,\n      stop_offset,\n      min_bundle_size=0,\n      splittable=True):\n    if not isinstance(start_offset, int):\n      raise TypeError(\n          'start_offset must be a number. Received: %r' % start_offset)\n    if stop_offset != range_trackers.OffsetRangeTracker.OFFSET_INFINITY:\n      if not isinstance(stop_offset, int):\n        raise TypeError(\n            'stop_offset must be a number. Received: %r' % stop_offset)\n      if start_offset >= stop_offset:\n        raise ValueError(\n            'start_offset must be smaller than stop_offset. Received %d and %d '\n            'for start and stop offsets respectively' %\n            (start_offset, stop_offset))\n\n    self._file_name = file_name\n    self._is_gcs_file = file_name.startswith('gs://') if file_name else False\n    self._start_offset = start_offset\n    self._stop_offset = stop_offset\n    self._min_bundle_size = min_bundle_size\n    self._file_based_source = file_based_source\n    self._splittable = splittable\n\n  def split(self, desired_bundle_size, start_offset=None, stop_offset=None):\n    if start_offset is None:\n      start_offset = self._start_offset","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/filebasedsource.py#L238-L274","documentation":"_FileBasedSource.__init__ requires stop_offset to be an int unless it is the sentinel OffsetRangeTracker.OFFSET_INFINITY, and raises TypeError otherwise. The stop offset bounds the region of the file the source reads, so a non-integer is rejected at construction time.","triggerScenarios":"Constructing a _FileBasedSource with stop_offset as a float (e.g. from division), a string from config/JSON, or None instead of int or OFFSET_INFINITY.","commonSituations":"Reading offsets from deserialized config; computing stop as file_size / 2 (float division); confusing None with OFFSET_INFINITY to mean 'read to end'.","solutions":["Pass an integer or the sentinel range_trackers.OffsetRangeTracker.OFFSET_INFINITY to read to end of file","Convert with int(stop_offset) or use floor division //","Fix config/JSON parsing so offsets are decoded as ints"],"exampleFix":"// before\nsrc = _FileBasedSource(path, 0, None)\n// after\nfrom apache_beam.io import range_trackers\nsrc = _FileBasedSource(path, 0, range_trackers.OffsetRangeTracker.OFFSET_INFINITY)","handlingStrategy":"validation","validationCode":"from apache_beam.io import range_trackers\nif stop_offset != range_trackers.OffsetRangeTracker.OFFSET_INFINITY and not isinstance(stop_offset, int):\n    raise TypeError(f'stop_offset must be int, got {type(stop_offset).__name__}')","typeGuard":"def is_valid_stop(v) -> bool:\n    from apache_beam.io import range_trackers\n    return v == range_trackers.OffsetRangeTracker.OFFSET_INFINITY or (isinstance(v, int) and not isinstance(v, bool))","tryCatchPattern":"try:\n    src = _FileBasedSource(path, start, stop)\nexcept TypeError as e:\n    if 'stop_offset must be a number' in str(e):\n        src = _FileBasedSource(path, start, int(stop))\n    else:\n        raise","preventionTips":["Use OffsetRangeTracker.OFFSET_INFINITY rather than None to mean 'to end'","Use // instead of / when computing offsets from file sizes","Validate offsets at config-load time, not at source construction"],"tags":["type-mismatch","offset","constructor"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}