apache/beam · error · ValueError

Parameter options, if specified, must be of type…

Error message

Parameter options, if specified, must be of type PipelineOptions. Received : %r

What it means

Pipeline.__init__ accepts either a PipelineOptions instance (or None) via options=, or an argv list. If options is given but is not a PipelineOptions (e.g. a dict or string), ValueError is raised. This prevents silently misusing the two parameter styles.

Solutions

  1. Pass a PipelineOptions instance: Pipeline(options=PipelineOptions([...])).
  2. Pass flags as the argv list instead: Pipeline(argv=['--project=p']).
  3. Convert a dict of flags to PipelineOptions by building flag strings.

Example fix

# before
p = Pipeline(options=['--runner=DirectRunner'])
# after
from apache_beam.options.pipeline_options import PipelineOptions
p = Pipeline(options=PipelineOptions(['--runner=DirectRunner']))
Defensive patterns

Strategy: type-guard

Validate before calling

if options is not None and not isinstance(options, PipelineOptions): options = PipelineOptions([f'--{k}={v}' for k, v in options.items()])

Type guard

def is_pipeline_options(v) -> bool:
    return v is None or isinstance(v, PipelineOptions)

Try / catch

try:
    p = Pipeline(options=options)
except ValueError as e:
    raise TypeError('options must be PipelineOptions or None; use argv for flags') from e

Prevention

When it happens

Trigger: Pipeline(runner, options={'project': 'p'}) or Pipeline(options='--project=p') — passing a dict/string where only PipelineOptions is allowed.

Common situations: Migrating code that previously passed a dict of flags, or passing the same string you'd give at the command line.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at sdks/python/apache_beam/pipeline.py:181

      ValueError: if either the runner or options argument is not
        of the expected type.
    """
    # Initializing logging configuration in case the user did not set it up.
    logging.basicConfig()

    if options is not None:
      if isinstance(options, PipelineOptions):
        # Make a deep copy of options since they could be overwritten in later
        # steps. However, the 'runner' object within 'options' is excluded from
        # the deep copy (it is shallow copied) due to potential issues with deep
        # copying specific runner instances, such as FlumeRunner.
        saved_runner = options.view_as(StandardOptions).runner
        options.view_as(StandardOptions).runner = None
        self._options = copy.deepcopy(options)
        self._options.view_as(StandardOptions).runner = saved_runner
        options.view_as(StandardOptions).runner = saved_runner
      else:
        raise ValueError(
            'Parameter options, if specified, must be of type PipelineOptions. '
            'Received : %r' % options)
    elif argv is not None:
      if isinstance(argv, list):
        self._options = PipelineOptions(argv)
      else:
        raise ValueError(
            'Parameter argv, if specified, must be a list. Received : %r' %
            argv)
    else:
      self._options = PipelineOptions([])

    FileSystems.set_options(self._options)

    if runner is None:
      runner = self._options.view_as(StandardOptions).runner
      if runner is None:
        runner = StandardOptions.DEFAULT_RUNNER

View on GitHub (pinned to 12126d8942)