{"record":{"id":"a8364b4dce4fc9d3","repo":"apache/beam","slug":"watch-restriction-was-neither-claimed-nor-checkpointed-r","errorCode":null,"errorMessage":"Watch restriction was neither claimed nor checkpointed: %r","messagePattern":"Watch restriction was neither claimed nor checkpointed: %r","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/watch.py","lineNumber":599,"sourceCode":"            max((output.timestamp for output in self._claimed_result.outputs),\n                default=None))\n        if cursor is not None:\n          completed = _retained(completed, cursor - self._allowed_lateness)\n      residual = _PollingGrowthState(\n          completed,\n          _max_watermark(\n              self._restriction.poll_watermark, self._claimed_result.watermark),\n          self._claimed_termination_state,\n          cursor)\n      self._restriction = _NonPollingGrowthState(self._claimed_result)\n    self._should_stop = True\n    return self._restriction, residual\n\n  def check_done(self) -> bool:\n    # Called after every process(); the single claim or a split sets the flag.\n    if self._should_stop:\n      return True\n    raise ValueError(\n        'Watch restriction was neither claimed nor checkpointed: %r' %\n        (self._restriction, ))\n\n  def current_progress(self) -> 'iobase.RestrictionProgress':\n    if self._should_stop:\n      return iobase.RestrictionProgress(completed=1.0, remaining=0.0)\n    return iobase.RestrictionProgress(completed=0.0, remaining=1.0)\n\n  def is_bounded(self) -> bool:\n    # A polling restriction is unbounded; a replay-then-stop one is bounded.\n    return isinstance(self._restriction, _NonPollingGrowthState)\n\n\n# ------------------------------------------------------------------------------\n# Splittable DoFn (its own restriction provider).\n# ------------------------------------------------------------------------------\n\n","sourceCodeStart":581,"sourceCodeEnd":617,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/watch.py#L581-L617","documentation":"Watch's _WatchRestrictionChecker (a RestrictionChecker) requires that after each process() call the restriction was either claimed (input consumed) or checkpointed (split off). check_done() raises ValueError if neither happened, meaning the DoFn's process did not invoke the restriction protocol correctly — an internal invariant of the Watch implementation.","triggerScenarios":"process() was skipped or short-circuited without claiming the restriction (e.g. empty poll result paths not calling restriction claim/checkpoint); customizing Watch or wrapping its DoFn so the claim/checkpoint call is bypassed; runner-invoked split/checkpoint interleaving breaking the flag.","commonSituations":"Modifying or subclassing Watch internals; Beam version bugs where certain poll_fn results (e.g. immediately complete results) skip the claim path; unusual runner behaviors around splitting.","solutions":["Upgrade Apache Beam to the latest patch version — this invariant error is often fixed in newer releases","If you wrapped or subclassed Watch's DoFn/restriction, ensure check_done's contract is respected: every process() must claim or checkpoint","Avoid manual manipulation of the restriction; use Watch's public API (watch() PTransform) only"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    result = p | beam.Watch(poll_fn, poll_interval=...) \nexcept ValueError as e:\n    if 'neither claimed nor checkpointed' in str(e):\n        log.error('Watch restriction protocol violated; check Beam version / customizations')\n    raise","preventionTips":["Do not subclass or wrap Watch internals; use the public watch() PTransform","Keep Beam up to date; check the issue tracker for this invariant error in your version","Test Watch pipelines on DirectRunner before production runners"],"tags":["python","apache-beam","invariant","restriction-tracking","watch-io"],"backgroundTag":"internal-invariant-violation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}