apache/beam · error · TypeError

Expected single output type hint for

Error message

Expected single output type hint for %s but got: %s

What it means

simple_output_type enforces that a function/transform has exactly one untagged output type hint. When the registered output_types tuple contains zero or multiple positional output types, Beam cannot return a single hint, so it raises TypeError listing the full output_types value.

Solutions

  1. Use a single positional type: @with_output_types(Tuple[int, str]) instead of @with_output_types(int, str)
  2. If outputs are tagged, access them via tagged_output_types() rather than simple_output_type
  3. If there are genuinely multiple independent outputs, model them as Tuple or a dict of tags
  4. Inspect self.output_types to confirm how many positional args were registered

Example fix

// before
@with_output_types(int, str)
def parse(x): ...
// after
from apache_beam.typehints import Tuple
@with_output_types(Tuple[int, str])
def parse(x): ...
Defensive patterns

Strategy: validation

Validate before calling

def has_single_output(th):
  args, _ = th.output_types
  return len(args) == 1

Try / catch

try:
  out = th.simple_output_type(context)
except TypeError:
  out = th.tagged_output_types()  # fallback for tagged/multi-output

Prevention

When it happens

Trigger: Declaring @with_output_types(int, str) (two positional hints) or with no positional hint but only kwargs, then something calls simple_output_type(context) expecting one return type, e.g. during pipeline type inference of a DoFn or PTransform.

Common situations: Multi-output transforms annotated with several positional types instead of a Tuple; a transform whose outputs are all tagged so positional args list is empty; copying an annotation pattern from a different transform.

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/23800b1b6d46258b. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/typehints/decorators.py:398

  def with_output_types(self, *args, **kwargs) -> 'IOTypeHints':
    return self._replace(
        output_types=(args, kwargs), origin=self._make_origin([self]))

  def with_input_types_from(self, other: 'IOTypeHints') -> 'IOTypeHints':
    return self._replace(
        input_types=other.input_types, origin=self._make_origin([self]))

  def with_output_types_from(self, other: 'IOTypeHints') -> 'IOTypeHints':
    return self._replace(
        output_types=other.output_types, origin=self._make_origin([self]))

  def simple_output_type(self, context):
    if self._has_output_types():
      args, _ = self.output_types
      # Note: kwargs may contain tagged output types, which are ignored here.
      # Use tagged_output_types() to access those.
      if len(args) != 1:
        raise TypeError(
            'Expected single output type hint for %s but got: %s' %
            (context, self.output_types))
      return args[0]

  def tagged_output_types(self):
    if not self._has_output_types():
      return {}
    _, tagged_output_types = self.output_types
    return tagged_output_types

  def has_simple_output_type(self):
    """Whether there's a single positional output type."""
    return (self.output_types and len(self.output_types[0]) == 1)

  def strip_pcoll(self):
    from apache_beam.pipeline import Pipeline
    from apache_beam.pvalue import PBegin
    from apache_beam.pvalue import PDone

View on GitHub (pinned to 12126d8942)