apache/beam · error · ValueError

Only one of context or default_environment may be specified.

Error message

Only one of context or default_environment may be specified.

What it means

ValueError raised in Pipeline.to_runner_api when both an explicit PipelineContext and a default_environment are supplied. The context already carries its own environment, so the two options are mutually exclusive.

Source

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

    self.visit(Visitor())
    return Visitor.ok

  def to_runner_api(
      self,
      return_context: bool = False,
      context: Optional['PipelineContext'] = None,
      use_fake_coders: bool = False,
      default_environment: Optional['environments.Environment'] = None
  ) -> beam_runner_api_pb2.Pipeline:
    """For internal use only; no backwards-compatibility guarantees."""
    from apache_beam.runners import pipeline_context
    if context is None:
      context = pipeline_context.PipelineContext(
          use_fake_coders=use_fake_coders,
          component_id_map=self.component_id_map,
          default_environment=default_environment)
    elif default_environment is not None:
      raise ValueError(
          'Only one of context or default_environment may be specified.')

    # The FlumeRunner is the only runner setting this option. Use getattr
    # because other runners do not have this option.
    context.enable_best_effort_deterministic_pickling = getattr(
        self.runner, 'enable_best_effort_deterministic_pickling', False)

    # The RunnerAPI spec requires certain transforms and side-inputs to have KV
    # inputs (and corresponding outputs).
    # Currently we only upgrade to KV pairs.  If there is a need for more
    # general shapes, potential conflicts will have to be resolved.
    # We also only handle single-input, and (for fixing the output) single
    # output, which is sufficient.
    # Also marks such values as requiring deterministic key coders.
    deterministic_key_coders = not self._options.view_as(
        TypeOptions).allow_non_deterministic_key_coders

    class ForceKvInputTypes(PipelineVisitor):

View on GitHub (pinned to 12126d8942)

Solutions

  1. Pass only one of the two: build the context with default_environment=env in its constructor, or pass default_environment=None
  2. If you need a custom environment inside the context, set it via context.environments
  3. Omit the explicit context and let Beam create one from default_environment

Example fix

// before
proto = p.to_runner_api(context=ctx, default_environment=env)
// after
ctx = pipeline_context.PipelineContext(default_environment=env)
proto = p.to_runner_api(context=ctx)
Defensive patterns

Strategy: validation

Validate before calling

assert not (context is not None and default_environment is not None), 'Pass only one of context or default_environment'

Try / catch

try:
    proto = p.to_runner_api(context=ctx, default_environment=env)
except ValueError as e:
    proto = p.to_runner_api(context=ctx)

Prevention

When it happens

Trigger: Calling pipeline.to_runner_api(context=ctx, default_environment=env), or runner APIs (run_pipeline/get_proto_pipeline) passing both parameters.

Common situations: Custom runners or test harnesses constructing a PipelineContext manually while also setting a default environment from options.

Related errors


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