apache/beam · error · RuntimeError

Asynchronous computation was cancelled.

Error message

Asynchronous computation was cancelled.

What it means

After the completed event fires, wait_for_completion checks whether the underlying Future was cancelled; if so it raises RuntimeError('Asynchronous computation was cancelled.'). This signals the recording's background computation was aborted rather than completed or failed with an exception.

Solutions

  1. Do not call wait_for_completion on a recording you have cancelled; create a new recording instead
  2. Treat RuntimeError as 'computation aborted' and re-trigger the computation (ib.collect or record again)
  3. Check recording state via the manager before waiting
  4. Avoid cancelling recordings mid-flight unless you also discard them

Example fix

// before
recording.cancel()
recording.wait_for_completion()
// after
recording.cancel()
recording = ib.recordings.record(pcolls, max_n=100)  # start a fresh recording
recording.wait_for_completion()
Defensive patterns

Strategy: try-catch

Type guard

def is_cancelled(rec):
    return rec._future is not None and rec._future.cancelled()

Try / catch

try:
    recording.wait_for_completion()
except RuntimeError as e:
    if 'cancelled' in str(e):
        recording = ib.recordings.record(pcolls, max_n=100)  # restart

Prevention

When it happens

Trigger: Calling Recording.cancel() on an active recording and then calling wait_for_completion; the recording manager cancelling a computation (e.g. a superseded or timed-out async compute) before the future resolved.

Common situations: Notebook code that cancels a recording on interrupt/timeout and later tries to read results from the same Recording object.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/490a8cbf160d5d9e. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/runners/interactive/recording_manager.py:161

  def result(self, timeout=None):
    return self._future.result(timeout=timeout)

  def done(self):
    return self._future.done()

  def exception(self, timeout=None):
    try:
      return self._future.exception(timeout=timeout)
    except TimeoutError:
      return None

  def wait_for_completion(self, timeout=None):
    if not self._completed_event.wait(timeout=timeout):
      raise TimeoutError(
          'Timeout waiting for asynchronous computation completion.')
    if self._future.cancelled():
      raise RuntimeError('Asynchronous computation was cancelled.')
    exc = self.exception()
    if exc:
      raise exc

  def _on_done(self, future: Future):
    try:
      if future.cancelled():
        self.update_display('Computation Cancelled.', 1.0)
        return

      exc = future.exception()
      if exc:
        self.update_display(f'Error: {exc}', 1.0)
        _LOGGER.error('Asynchronous computation failed: %s', exc, exc_info=exc)
      else:
        self.update_display('Computation Finished Successfully.', 1.0)
        res = future.result()
        if res and res.state == PipelineState.DONE:

View on GitHub (pinned to 12126d8942)