apache/beam · error · WontImplementError

len(df) is not currently supported because it produces a…

Error message

len(df) is not currently supported because it produces a non-deferred result. Consider using df.length() instead.

What it means

len(df) on a DeferredDataFrame would have to compute the number of rows immediately, producing a concrete (non-deferred) scalar — which breaks the deferred-execution contract of the Beam DataFrame API. The API raises WontImplementError and points you to df.length(), which returns a deferred scalar expression integrated into the pipeline.

Solutions

  1. Use df.length() which returns a deferred expression; feed it into the pipeline or collect it via compute().
  2. If a concrete count is required, call beam.dataframe.compute(df.length()) (or to_pandas on the length expression) at a pipeline boundary.
  3. Replace `if len(df)` checks with logic that stays deferred, or restructure to avoid data-dependent control flow.

Example fix

// before
n = len(df)
// after
n_expr = df.length()  # deferred; compute() it if a concrete value is needed
Defensive patterns

Strategy: try-catch

Validate before calling

if isinstance(df, DeferredDataFrame):
    n = df.length()  # deferred
else:
    n = len(df)

Type guard

from apache_beam.dataframe.frames import DeferredDataFrame
def is_deferred_frame(obj) -> bool:
    return isinstance(obj, DeferredDataFrame)

Try / catch

try:
    n = len(df)
except frame_base.WontImplementError:
    n = beam.dataframe.compute(df.length())

Prevention

When it happens

Trigger: Calling len(df) or bool(df) (which uses __len__ for truthiness) on a DeferredDataFrame.

Common situations: Debug prints of row counts in notebooks; `if len(df) == 0:` guards ported from pandas; assertions in pipeline code converted from pandas to Beam.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at sdks/python/apache_beam/dataframe/frames.py:778

    used in arithmetic with :class:`DeferredSeries` or
    :class:`DeferredDataFrame` instances."""
    lengths = expressions.ComputedExpression(
        'get_lengths',
        # Wrap scalar results in a Series for easier concatenation later
        lambda df: pd.Series(len(df)),
        [self._expr],
        requires_partition_by=partitionings.Arbitrary(),
        preserves_partition_by=partitionings.Singleton())

    with expressions.allow_non_parallel_operations(True):
      return frame_base.DeferredFrame.wrap(
          expressions.ComputedExpression(
              'sum_lengths', lambda lengths: lengths.sum(), [lengths],
              requires_partition_by=partitionings.Singleton(),
              preserves_partition_by=partitionings.Singleton()))

  def __len__(self):
    raise frame_base.WontImplementError(
        "len(df) is not currently supported because it produces a non-deferred "
        "result. Consider using df.length() instead.",
        reason="non-deferred-result")

  @property  # type: ignore
  @frame_base.with_docs_from(pd.DataFrame)
  def empty(self):
    empties = expressions.ComputedExpression(
        'get_empties',
        # Wrap scalar results in a Series for easier concatenation later
        lambda df: pd.Series(df.empty),
        [self._expr],
        requires_partition_by=partitionings.Arbitrary(),
        preserves_partition_by=partitionings.Singleton())

    with expressions.allow_non_parallel_operations(True):
      return frame_base.DeferredFrame.wrap(
          expressions.ComputedExpression(

View on GitHub (pinned to 12126d8942)