{"record":{"id":"4b52dd9d7ea8c98f","repo":"apache/beam","slug":"target-batch-duration-secs-s-must-be-positive","errorCode":null,"errorMessage":"target_batch_duration_secs (%s) must be positive","messagePattern":"target_batch_duration_secs \\((.+?)\\) must be positive","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/util.py","lineNumber":529,"sourceCode":"      min_batch_size=1,\n      max_batch_size=10000,\n      target_batch_overhead=.05,\n      target_batch_duration_secs=10,\n      target_batch_duration_secs_including_fixed_cost=None,\n      variance=0.25,\n      clock=time.time,\n      ignore_first_n_seen_per_batch_size=0,\n      record_metrics=True):\n    if min_batch_size > max_batch_size:\n      raise ValueError(\n          \"Minimum (%s) must not be greater than maximum (%s)\" %\n          (min_batch_size, max_batch_size))\n    if target_batch_overhead and not 0 < target_batch_overhead <= 1:\n      raise ValueError(\n          \"target_batch_overhead (%s) must be between 0 and 1\" %\n          (target_batch_overhead))\n    if target_batch_duration_secs and target_batch_duration_secs <= 0:\n      raise ValueError(\n          \"target_batch_duration_secs (%s) must be positive\" %\n          (target_batch_duration_secs))\n    if (target_batch_duration_secs_including_fixed_cost and\n        target_batch_duration_secs_including_fixed_cost <= 0):\n      raise ValueError(\n          \"target_batch_duration_secs_including_fixed_cost \"\n          \"(%s) must be positive\" %\n          (target_batch_duration_secs_including_fixed_cost))\n    if not (target_batch_overhead or target_batch_duration_secs or\n            target_batch_duration_secs_including_fixed_cost):\n      raise ValueError(\n          \"At least one of target_batch_overhead or \"\n          \"target_batch_duration_secs or \"\n          \"target_batch_duration_secs_including_fixed_cost must be positive.\")\n    if ignore_first_n_seen_per_batch_size < 0:\n      raise ValueError(\n          'ignore_first_n_seen_per_batch_size (%s) must be non '\n          'negative' % (ignore_first_n_seen_per_batch_size))","sourceCodeStart":511,"sourceCodeEnd":547,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/util.py#L511-L547","documentation":"Raised in _BatchSizeEstimator (BatchElements) __init__ when target_batch_duration_secs is provided but <= 0. The target batch duration is a wall-clock goal per batch and must be a positive number of seconds; zero or negative values are invalid.","triggerScenarios":"BatchElements(target_batch_duration_secs=0) or a negative value; passing a datetime.timedelta without converting to seconds.","commonSituations":"Computing the duration from a subtraction that yields 0; passing a timedelta object directly (truthy but invalid) instead of timedelta.total_seconds(); config default of 0 meaning 'unset' colliding with the truthiness check.","solutions":["Pass a positive number of seconds, e.g. target_batch_duration_secs=1.0.","Convert timedeltas explicitly: target_batch_duration_secs=td.total_seconds().","Guard at the call site: if target_duration and target_duration <= 0: raise a clear config error before constructing the transform.","If 0 means 'unset' in your config, omit the argument entirely (None) rather than passing 0."],"exampleFix":"// before\nbeam.BatchElements(target_batch_duration_secs=timedelta(seconds=2))\n\n// after\nbeam.BatchElements(target_batch_duration_secs=timedelta(seconds=2).total_seconds())","handlingStrategy":"validation","validationCode":"if target_batch_duration_secs is not None and target_batch_duration_secs <= 0:\n    raise ValueError('target_batch_duration_secs must be > 0 seconds')","typeGuard":"def valid_duration_secs(x):\n    return x is None or (isinstance(x, (int, float)) and x > 0)","tryCatchPattern":"try:\n    t = beam.BatchElements(target_batch_duration_secs=d)\nexcept ValueError:\n    logging.warning('invalid target_batch_duration_secs=%r; omitting', d)\n    t = beam.BatchElements(target_batch_overhead=0.05)","preventionTips":["Always convert timedeltas with .total_seconds() before passing.","Use None (omit) for 'unset' instead of 0.","Validate computed durations (subtractions can yield 0) before constructing."],"tags":["python","apache-beam","batchelements","config-validation"],"backgroundTag":"invalid-argument-value","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"}