apache/beam · error · ValueError

type annotation for multiple outputs is not allowed yet: %s

Error message

type annotation for multiple outputs is not allowed yet: %s

What it means

In the expansion service's Expand handler, when a transform carries output coder hints for more than one output, the service refuses to apply a with_output_types annotation (only single-output annotation is implemented) and raises ValueError. The expansion itself may be valid; only multi-output type annotation is unsupported.

Source

Thrown at sdks/python/apache_beam/runners/portability/expansion_service.py:90

          request.components,
          default_environment=self._default_environment,
          namespace=request.namespace,
          requirements=request.requirements)
      producers = {
          pcoll_id: (context.transforms.get_by_id(t_id), pcoll_tag)
          for t_id, t_proto in request.components.transforms.items()
          for pcoll_tag, pcoll_id in t_proto.outputs.items()
      }
      transform = with_pipeline(
          ptransform.PTransform.from_runner_api(request.transform, context))
      if len(request.output_coder_requests) == 1:
        output_coder = {
            k: context.element_type_from_coder_id(v)
            for k, v in request.output_coder_requests.items()
        }
        transform = transform.with_output_types(list(output_coder.values())[0])
      elif len(request.output_coder_requests) > 1:
        raise ValueError(
            'type annotation for multiple outputs is not allowed yet: %s' %
            request.output_coder_requests)
      inputs = transform._pvaluish_from_dict({
          tag: with_pipeline(
              context.pcollections.get_by_id(pcoll_id), pcoll_id)
          for tag, pcoll_id in request.transform.inputs.items()
      })
      if not inputs:
        inputs = pipeline
      with external.ExternalTransform.outer_namespace(request.namespace):
        result = pipeline.apply(
            transform, inputs, request.transform.unique_name)
      expanded_transform = pipeline._root_transform().parts[-1]
      # TODO(BEAM-1833): Use named outputs internally.
      if isinstance(result, dict):
        expanded_transform.outputs = result
      pipeline_proto = pipeline.to_runner_api(context=context)
      # TODO(BEAM-1833): Use named inputs internally.

View on GitHub (pinned to 12126d8942)

Solutions

  1. Send at most one output coder request (for the main output) until multi-output annotation is supported.
  2. Expand without output coder hints and set coders/types on the resulting PCollections afterwards.
  3. Track/patch upstream expansion_service.py to add multi-output type annotation support.

Example fix

// before
request.output_coder_requests = {'out0': 'coder0', 'out1': 'coder1'}
// after
request.output_coder_requests = {}  # let the transform infer output types
Defensive patterns

Strategy: fallback

Validate before calling

if len(request.output_coder_requests) > 1:
    request.output_coder_requests = {}  # fall back to inference

Try / catch

try:
    result = expand_via_service(request)
except ValueError as e:
    if 'multiple outputs' in str(e):
        request.output_coder_requests = {}
        result = expand_via_service(request)
    else:
        raise

Prevention

When it happens

Trigger: Calling the ExpansionService Expand RPC for a transform with len(request.output_coder_requests) > 1 — i.e. a multi-output transform (partition, multi-tag DoFn) with per-output coder hints.

Common situations: Cross-language expansion of multi-output transforms from an SDK that populates output_coder_requests for every tag; Java pipelines expanded via the Python expansion service with type hints on all outputs.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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