apache/beam · error · ValueError

Either a read_artifact_location or write_artifact_location…

Error message

Either a read_artifact_location or write_artifact_location must be specified to initialize MLTransform

What it means

MLTransform requires at least one artifact location: either write_artifact_location (produce mode, persisting transform artifacts) or read_artifact_location (consume mode, loading previously written artifacts). With neither set, initialization fails with this ValueError.

Solutions

  1. Add write_artifact_location=<path> when applying transforms for the first time.
  2. Use read_artifact_location=<path> to reuse artifacts from a prior MLTransform run.
  3. Ensure the path is accessible to the pipeline (local path for DirectRunner, GCS/DFS path for distributed runners).

Example fix

// before
MLTransform(transforms=[MLTransformsWrapper(...)])
// after
MLTransform(write_artifact_location='gs://bucket/artifacts', transforms=[MLTransformsWrapper(...)])
Defensive patterns

Strategy: validation

Validate before calling

def make_mltransform(**kw):
    if not kw.get('read_artifact_location') and not kw.get('write_artifact_location'):
        raise ValueError('artifact location required')
    return MLTransform(**kw)

Type guard

def artifact_location_present(cfg) -> bool:
    return bool(cfg.get('read_artifact_location') or cfg.get('write_artifact_location'))

Try / catch

try:
    t = MLTransform(transforms=ts)
except ValueError as e:
    if 'must be specified' in str(e):
        t = MLTransform(write_artifact_location='gs://bucket/artifacts', transforms=ts)
    else:
        raise

Prevention

When it happens

Trigger: Calling MLTransform(transforms=[...]) with no artifact_location arguments at all.

Common situations: Omitting artifact_location when following quickstart snippets that abbreviated the API; constructing MLTransform programmatically and forgetting the location parameter.

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


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

Appendix: source

Thrown at sdks/python/apache_beam/ml/transforms/base.py:360

        applied to the dataset and generated values like min, max from
        ScaleTo01, and mean, var from ScaleToZScore. Note that when consuming
        artifacts, it is not necessary to pass the transforms since they are
        inherently stored within the artifacts themselves. The value assigned
        to `read_artifact_location` should be a valid storage path where the
        artifacts can be read from. Only one of write_artifact_location and
        read_artifact_location should be specified.
      transforms: A list of transforms to apply to the data. All the transforms
        are applied in the order they are specified. The input of the
        i-th transform is the output of the (i-1)-th transform. Multi-input
        transforms are not supported yet.
    """
    if read_artifact_location and write_artifact_location:
      raise ValueError(
          'Only one of read_artifact_location or write_artifact_location can '
          'be specified to initialize MLTransform')

    if not read_artifact_location and not write_artifact_location:
      raise ValueError(
          'Either a read_artifact_location or write_artifact_location must be '
          'specified to initialize MLTransform')

    if read_artifact_location:
      artifact_location = read_artifact_location
      artifact_mode = ArtifactMode.CONSUME
      if transforms:
        raise ValueError(
            'Transforms should not be passed in read mode. In read mode, '
            'the transforms are read from the artifact location.')

    else:
      artifact_location = write_artifact_location  # type: ignore[assignment]
      artifact_mode = ArtifactMode.PRODUCE

    self._parent_artifact_location = artifact_location

    self._artifact_mode = artifact_mode

View on GitHub (pinned to 12126d8942)