apache/beam · error · ValueError

op must be one of ('idxmax', 'idxmin'). got {op!r}.

Error message

op must be one of ('idxmax', 'idxmin'). got {op!r}.

What it means

apache_beam.dataframe (the pandas-on-Beam API) implements idxmax/idxmin via a single internal helper _idxmaxmin_helper that dispatches on the op string. The helper only accepts 'idxmax' or 'idxmin'; any other op value means an internal dispatch bug, since users call idxmin()/idxmax() which hardcode the op. This ValueError guards against the helper being invoked incorrectly.

Source

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

      base=pd.DataFrame,
      requires_partition_by=partitionings.Arbitrary(),
      preserves_partition_by=partitionings.Singleton())
  add_prefix = frame_base._proxy_method(
      'add_prefix',
      base=pd.DataFrame,
      requires_partition_by=partitionings.Arbitrary(),
      preserves_partition_by=partitionings.Singleton())

  info = frame_base.wont_implement_method(
      pd.Series, 'info', reason="non-deferred-result")

  def _idxmaxmin_helper(self, op, **kwargs):
    if op == 'idxmax':
      func = pd.Series.idxmax
    elif op == 'idxmin':
      func = pd.Series.idxmin
    else:
      raise ValueError(
          "op must be one of ('idxmax', 'idxmin'). "
          f"got {op!r}.")

    def compute_idx(s):
      index = func(s, **kwargs)
      if pd.isna(index):
        return s
      else:
        return s.loc[[index]]

    # Avoids empty Series error when evaluating proxy
    index_dtype = self._expr.proxy().index.dtype
    index = pd.Index([], dtype=index_dtype)
    proxy = self._expr.proxy().copy()
    proxy.index = index
    proxy = pd.concat([
        proxy,
        pd.Series([1], index=np.asarray(['0']).astype(proxy.index.dtype))

View on GitHub (pinned to 12126d8942)

Solutions

  1. Use the public API: call df.idxmax() or series.idxmin() instead of invoking _idxmaxmin_helper manually.
  2. If writing a wrapper, pass only the literal strings 'idxmax' or 'idxmin' as op.
  3. Check for typos/whitespace in the op value; print repr(op) to verify.
  4. If this appears through normal idxmax/idxmin usage, file a bug against apache_beam.

Example fix

// before
func = getattr(pd.Series, op)  # op could be anything
helper(op)
// after
if op in ('idxmax', 'idxmin'):
    _idxmaxmin_helper(op)
else:
    df.idxmax()  # use the public method
Defensive patterns

Strategy: type-guard

Validate before calling

if op not in ('idxmax', 'idxmin'):
    raise ValueError(f'op must be idxmax or idxmin, got {op!r}')

Type guard

def is_valid_idx_op(op) -> bool:
    return op in ('idxmax', 'idxmin')

Try / catch

try:
    result = df.idxmax()
except ValueError as e:
    logger.error('idx op dispatch failed: %s', e)
    result = None

Prevention

When it happens

Trigger: Calling _idxmaxmin_helper directly with an op value other than 'idxmax' or 'idxmin' (e.g. a typo, None, or a patched/monkey-patched dispatch); the public idxmin/idxmax methods pass literal values so this is effectively unreachable through the public API.

Common situations: Contributors extending the frames module who add a new idx-style op but pass a wrong string; debugging code that introspects or wraps internal helpers; fat-fingering op='idxmax' vs 'idxmax ' in custom wrappers.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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