apache/beam · error · ValueError

axis must be one of ('index', 0, 'columns', 1). got {axis!r}

Error message

axis must be one of ('index', 0, 'columns', 1). got {axis!r}.

What it means

xs() in Beam DataFrames supports selecting from either the index (axis=0/'index') or, in the branch that raises, validates that any other axis value is at least a legal pandas axis before delegating. An axis outside ('index', 0, 'columns', 1) is rejected with ValueError.

Source

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

  @frame_base.with_docs_from(pd.DataFrame)
  @frame_base.args_to_kwargs(pd.DataFrame)
  @frame_base.populate_defaults(pd.DataFrame)
  def xs(self, key, axis, level, **kwargs):
    """Note that ``xs(axis='index')`` will raise a ``KeyError`` at execution
    time if the key does not exist in the index."""

    if axis in ('columns', 1):
      # Special case for axis=columns. This is a simple project that raises a
      # KeyError at construction time for missing columns.
      return frame_base.DeferredFrame.wrap(
          expressions.ComputedExpression(
              'xs', lambda df: df.xs(key, axis=axis, **kwargs), [self._expr],
              requires_partition_by=partitionings.Arbitrary(),
              preserves_partition_by=partitionings.Arbitrary()))
    elif axis not in ('index', 0):
      # Make sure that user's axis is valid
      raise ValueError(
          "axis must be one of ('index', 0, 'columns', 1). "
          f"got {axis!r}.")

    if not isinstance(key, tuple):
      key_size = 1
      key_series = pd.Series([key], index=[key])
    else:
      key_size = len(key)
      key_series = pd.Series([key], pd.MultiIndex.from_tuples([key]))

    key_expr = expressions.ConstantExpression(
        key_series, proxy=key_series.iloc[:0])

    if level is None:
      reindexed = self
    else:
      if not isinstance(level, list):
        level = [level]

View on GitHub (pinned to 12126d8942)

Solutions

  1. Use axis='index' or axis=0 when selecting index levels with xs
  2. Use axis='columns' or axis=1 only if selecting from columns, and verify support
  3. Validate axis values against the allowed set before calling

Example fix

// before
df.xs('L1', axis='rows')
// after
df.xs('L1', axis='index')
Defensive patterns

Strategy: validation

Validate before calling

if axis not in ('index', 0, 'columns', 1):
    raise ValueError(f"invalid xs axis: {axis!r}")
out = df.xs(key, axis=axis)

Type guard

def valid_xs_axis(axis):
    return axis in ('index', 0, 'columns', 1)

Try / catch

try:
    out = df.xs(key, axis=axis)
except ValueError:
    out = df.xs(key, axis='index')  # index selection is the supported default

Prevention

When it happens

Trigger: df.xs('k', axis='rows') or df.xs('k', axis=2) — an invalid axis spelling/type passed to xs; note axis=1/'columns' is also not implemented on the index path (only 'index'/0 is handled before this check).

Common situations: Typos like 'row'/'Rows'; integer/string confusion after refactoring; copying pandas snippets that used axis=1 for column-level xs without realizing the Beam path differs.

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