apache/beam · error · WontImplementError

replace(method={method!r}) is not supported because it is or

Error message

replace(method={method!r}) is not supported because it is order sensitive. Only replace(method=None) is supported.

What it means

replace(method='pad'/'nearest'/...) interpolates replacements based on data order, which Beam cannot guarantee. It is only raised when to_replace is NOT a dict and value is left at its default, because pandas only honors method in that case. Passing method=None (or to_replace as a dict, or an explicit value) is supported.

Source

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

  @frame_base.with_docs_from(pd.DataFrame)
  @frame_base.args_to_kwargs(pd.DataFrame)
  @frame_base.populate_defaults(pd.DataFrame)
  @frame_base.maybe_inplace
  def replace(self, to_replace, value, limit, method, **kwargs):
    """``method`` is not supported in the Beam DataFrame API because it is
    order-sensitive. It cannot be specified.

    If ``limit`` is specified this operation is not parallelizable."""
    # pylint: disable-next=c-extension-no-member
    value_compare = None if PD_VERSION < (1, 4) else lib.no_default
    if method is not None and not isinstance(to_replace,
                                             dict) and value is value_compare:
      # pandas only relies on method if to_replace is not a dictionary, and
      # value is the <no_default> value. This is different than
      # if ``None`` is explicitly passed for ``value``. In this case, it will be
      # respected
      raise frame_base.WontImplementError(
          f"replace(method={method!r}) is not supported because it is "
          "order sensitive. Only replace(method=None) is supported.",
          reason="order-sensitive")

    if limit is None:
      requires_partition_by = partitionings.Arbitrary()
    else:
      requires_partition_by = partitionings.Singleton(
          reason=(
              f"replace(limit={limit!r}) cannot currently be parallelized. It "
              "requires collecting all data on a single node."))
    return frame_base.DeferredFrame.wrap(
        expressions.ComputedExpression(
            'replace', lambda df: df.replace(
                to_replace=to_replace, value=value, limit=limit, method=method,
                **kwargs), [self._expr],
            preserves_partition_by=partitionings.Arbitrary(),
            requires_partition_by=requires_partition_by))

View on GitHub (pinned to 12126d8942)

Solutions

  1. Pass an explicit value: series.replace(to_replace, value=<replacement>).
  2. Pass to_replace as a dict mapping old->new values, which makes method irrelevant.
  3. Set method=None and supply a value.
  4. Use fillna with an explicit value for sentinel replacement.

Example fix

// before
s = s.replace(-1, method='pad')
// after
s = s.replace(-1, value=None)  # or s.replace({-1: 0})
Defensive patterns

Strategy: validation

Validate before calling

if method is not None and not isinstance(to_replace, dict) and value is pd.api.types.pandas_dtype.__class__ if False else (method is not None and not isinstance(to_replace, dict)):
    raise ValueError('Pass value= explicitly or use a dict for to_replace')

Type guard

def replace_is_deferrable(to_replace, value, method=None) -> bool:
    return method is None or isinstance(to_replace, dict) or value is not None

Try / catch

try:
    s = s.replace(-1, method='pad')
except frame_base.WontImplementError:
    s = s.replace({-1: 0})

Prevention

When it happens

Trigger: series.replace([1,2], method='pad') — i.e. replace with a scalar/list to_replace, no explicit value, and a non-None method — on a deferred frame.

Common situations: Porting pandas forward-fill-style replace calls; legacy pandas code using replace(method='pad') (deprecated in pandas 2.x anyway); cleaning pipelines that interpolate missing sentinels.

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/b38d135cbdd5a14b. Report an issue: GitHub.