apache/beam · error · RuntimeError
Columns are not specified. Please specify the column for…
Error message
Columns are not specified. Please specify the column for the op %s
What it means
All TFT transform op base classes (ApplyTransforms base in tft.py) require a non-empty columns list identifying which PCollection columns the transform applies to. The __init__ raises a RuntimeError when columns is falsy (None, empty list), because apply_transform would otherwise have no target column.
Solutions
- Pass the target column name(s): e.g. ScaleToZScore(columns=['feature_1']).
- Verify the source of the columns list is non-empty before constructing configs.
- Validate column names against the PCollection schema so downstream key errors are also avoided.
Example fix
# before transform = tft.ScaleToZScore() # columns missing # after transform = tft.ScaleToZScore(columns=['age'])
Defensive patterns
Strategy: validation
Validate before calling
def make_scale_zscore(columns):
if not columns:
raise ValueError('columns must be a non-empty list of column names')
return tft.ScaleToZScore(columns=columns) Type guard
def has_columns(columns) -> bool:
return isinstance(columns, (list, tuple)) and len(columns) > 0 and all(isinstance(c, str) for c in columns) Try / catch
try:
transforms = [tft.ScaleToZScore(columns=cols)]
except RuntimeError as e:
if 'Columns are not specified' in str(e):
raise ValueError(f'Provide target columns for transform: {e}') from e
raise Prevention
- Always pass columns as the first argument to every TFT transform config.
- Validate the transform-config list (non-empty columns) before building MLTransform.
- Use keyword arguments (columns=[...]) to avoid positional mix-ups.
- Add a schema test asserting each config targets an existing column.
When it happens
Trigger: Constructing a TFT transform config like ScaleToZScore(), ScaleMinMax(), ComputeAndApplyVocab() with columns=None or columns=[] (or omitting the first positional argument).
Common situations: Building transform configs programmatically from empty config lists, copy-pasting a transform instantiation without filling in column names, or a config loader returning an empty columns key.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- artifact_location is not specified. Please specify the…
- A BigQuery table or a query must be specified
- A has been supplied to the model handler, but the required…
- bucket_boundaries requires length_fn to be set.
- combine_fn must be provided
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/61abaa4760db5e6b.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/ml/transforms/tft.py:97
# TODO: https://github.com/apache/beam/pull/29016
# Add support for outputting artifacts to a text file in human readable form.
class TFTOperation(BaseOperation[common_types.TensorType,
common_types.TensorType]):
def __init__(self, columns: list[str]) -> None:
"""
Base Operation class for TFT data processing transformations.
Processing logic for the transformation is defined in the
apply_transform() method. If you have a custom transformation that is not
supported by the existing transforms, you can extend this class
and implement the apply_transform() method.
Args:
columns: List of column names to apply the transformation.
"""
super().__init__(columns)
if not columns:
raise RuntimeError(
"Columns are not specified. Please specify the column for the "
" op %s" % self.__class__.__name__)
def get_ptransform_for_processing(self, **kwargs) -> beam.PTransform:
from apache_beam.ml.transforms.handlers import TFTProcessHandler
params = {}
artifact_location = kwargs.get('artifact_location')
if not artifact_location:
raise RuntimeError(
"artifact_location is not specified. Please specify the "
"artifact_location for the op %s" % self.__class__.__name__)
artifact_mode = kwargs.get('artifact_mode')
if artifact_mode:
params['artifact_mode'] = artifact_mode
return TFTProcessHandler(artifact_location=artifact_location, **params)
@tf.functionView on GitHub (pinned to 12126d8942)