apache/beam · error · NotImplementedError

type(key)

Error message

type(key)

What it means

In _DeferredLoc.__getitem__, a list-of-booleans key (boolean list aligned by numerical position) is not implemented, so NotImplementedError(type(key)) is raised. Beam supports tuple, plain-list-of-labels (with caveats), slices, deferred boolean Series, and callables — but not boolean lists.

Solutions

  1. Convert the boolean list to a pandas Series (or Beam deferred Series) with the correct index and use that as the key.
  2. Use a callable key: df.loc[lambda df: pd.Series(bools, index=df.index)].
  3. Filter with an expression producing a deferred boolean Series instead of a materialized list.

Example fix

// before
df.loc[[True, False, True]]
# after
df.loc[pd.Series([True, False, True], index=df.index)]  # or a deferred bool Series
Defensive patterns

Strategy: type-guard

Validate before calling

if isinstance(key, list) and key and isinstance(key[0], bool):
    key = pd.Series(key, index=df.index)

Type guard

def is_loc_safe_key(key) -> bool:
    import pandas as pd
    return (isinstance(key, slice) or isinstance(key, pd.Series)
            or (isinstance(key, tuple) and all(isinstance(k, (slice, pd.Series)) for k in key)))

Try / catch

try:
    out = beam_df.loc[key]
except NotImplementedError as e:
    if str(e) == str(type(key)):
        out = beam_df.loc[pd.Series(list(key), index=beam_df.index)]

Prevention

When it happens

Trigger: df.loc[[True, False, True, ...]] on a Beam deferred DataFrame with a plain Python list of booleans.

Common situations: Copying pandas masking code that built a bool list from external logic; converting a numpy bool array to list and using it as .loc key.

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

Appendix: source

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

  def nlevels(self):
    return self._frame._expr.proxy().index.nlevels

  def __getattr__(self, name):
    raise NotImplementedError('index.%s' % name)


@populate_not_implemented(pd.core.indexing._LocIndexer)
class _DeferredLoc(object):
  def __init__(self, frame):
    self._frame = frame

  def __getitem__(self, key):
    if isinstance(key, tuple):
      rows, cols = key
      return self[rows][cols]
    elif isinstance(key, list) and key and isinstance(key[0], bool):
      # Aligned by numerical key.
      raise NotImplementedError(type(key))
    elif isinstance(key, list):
      # Select rows, but behaves poorly on missing values.
      raise NotImplementedError(type(key))
    elif isinstance(key, slice):
      args = [self._frame._expr]
      func = lambda df: df.loc[key]
    elif isinstance(key, frame_base.DeferredFrame):
      func = lambda df, key: df.loc[key]
      if pd.core.dtypes.common.is_bool_dtype(key._expr.proxy()):
        # Boolean indexer, just pass it in as-is
        args = [self._frame._expr, key._expr]
      else:
        # Likely a DeferredSeries of labels, overwrite the key's index with it's
        # values so we can colocate them with the labels they're selecting
        def data_to_index(s):
          s = s.copy()
          s.index = s
          return s

View on GitHub (pinned to 12126d8942)