apache/beam · error · ValueError

artifact_mode must be either `produce` or `consume`.

Error message

artifact_mode must be either `produce` or `consume`.

What it means

MLTransform validates artifact_mode at construction: it controls whether the transform writes ('produce') or reads ('consume') artifacts like saved model weights and transforms metadata. Any value other than the two allowed strings raises ValueError.

Solutions

  1. Use artifact_mode='produce' when the pipeline generates artifacts.
  2. Use artifact_mode='consume' when applying saved artifacts.
  3. Fix casing/typos — the check is case-sensitive.

Example fix

// before
MLTransform(artifact_location=uri, artifact_mode='write')
// after
MLTransform(artifact_location=uri, artifact_mode='produce')
Defensive patterns

Strategy: validation

Validate before calling

assert artifact_mode in ('produce', 'consume'), f"got {artifact_mode!r}"

Try / catch

try:
    t = MLTransform(artifact_location=uri, artifact_mode=mode)
except ValueError as e:
    if 'artifact_mode' in str(e):
        t = MLTransform(artifact_location=uri, artifact_mode='produce')

Prevention

When it happens

Trigger: MLTransform(artifact_location=..., artifact_mode='write') or 'PRODUCE' or any misspelled value — only the exact strings 'produce' and 'consume' pass.

Common situations: Uppercasing the mode for style consistency; using verbs like 'read'/'write' from another framework's API.

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

Appendix: source

Thrown at sdks/python/apache_beam/ml/transforms/handlers.py:169

class TFTProcessHandler(ProcessHandler[tft_process_handler_input_type,
                                       tft_process_handler_output_type]):
  def __init__(
      self,
      *,
      artifact_location: str,
      transforms: Optional[Sequence[TFTOperation]] = None,
      artifact_mode: str = ArtifactMode.PRODUCE):
    """
    A handler class for processing data with TensorFlow Transform (TFT)
    operations.
    """
    self.transforms = transforms if transforms else []
    self.transformed_schema: dict[str, type] = {}
    self.artifact_location = artifact_location
    self.artifact_mode = artifact_mode
    if artifact_mode not in ['produce', 'consume']:
      raise ValueError('artifact_mode must be either `produce` or `consume`.')

  def append_transform(self, transform):
    self.transforms.append(transform)

  def _map_column_names_to_types(self, row_type):
    """
    Return a dictionary of column names and types.
    Args:
      element_type: A type of the element. This could be a NamedTuple or a Row.
    Returns:
      A dictionary of column names and types.
    """
    try:
      if not isinstance(row_type, RowTypeConstraint):
        row_type = RowTypeConstraint.from_user_type(row_type)

      inferred_types = {name: typ for name, typ in row_type._fields}

View on GitHub (pinned to 12126d8942)