apache/beam · error · ValueError

Unknown output name "{tag}" from {by}

Error message

Unknown output name "{tag}" from {by}

What it means

Beam YAML's `split` function validates that the output tag returned by the user's `by` function is one of the declared output names. If the tag is a valid string but not present in `outputs` and no `unknown_output` fallback is configured, a ValueError is raised (yaml_mapping.py:823). This prevents silently creating undeclared PCollections.

Source

Thrown at sdks/python/apache_beam/yaml/yaml_mapping.py:823

  if error_output in outputs:
    raise ValueError(
        f'Error handling output "{error_output}" '
        f'cannot be among the listed outputs {outputs}')
  T = TypeVar('T')

  def split(element):
    tag = split_fn(element)
    if tag is None:
      tag = unknown_output
    if not isinstance(tag, str):
      raise ValueError(
          f'Returned output name "{tag}" of type {type(tag)} '
          f'from "{by}" must be a string.')
    if tag not in outputs:
      if unknown_output:
        tag = unknown_output
      else:
        raise ValueError(f'Unknown output name "{tag}" from {by}')
    return beam.pvalue.TaggedOutput(tag, element)

  output_set = set(outputs)
  if unknown_output:
    output_set.add(unknown_output)
  if error_output:
    output_set.add(error_output)
  mapping_transform = beam.Map(split)
  if error_output:
    mapping_transform = mapping_transform.with_exception_handling(
        **exception_handling_args(error_handling))
  else:
    mapping_transform = mapping_transform.with_outputs(*output_set)
  splits = pcoll | mapping_transform.with_input_types(T).with_output_types(T)
  result = {out: getattr(splits, out) for out in output_set}
  for tag, out in result.items():
    if tag != error_output:
      out.element_type = pcoll.element_type

View on GitHub (pinned to 12126d8942)

Solutions

  1. Make the split function return exactly one of the strings listed in the transform's `outputs` mapping.
  2. Fix typos/casing mismatches between returned tags and declared output names.
  3. Configure an `unknown_output` value so unmatched tags are routed to a fallback output instead of raising.

Example fix

// before
def split(row): return 'high_value' if row.total > 100 else 'lowvalue'
// after
def split(row): return 'high_value' if row.total > 100 else 'low_value'  # matches outputs: [high_value, low_value]
Defensive patterns

Strategy: validation

Validate before calling

def check_outputs(fn, sample_row, outputs):
    tag = fn(sample_row)
    assert isinstance(tag, str) and tag in outputs, f'tag {tag!r} not in {sorted(outputs)}'

Type guard

def is_known_output(tag, outputs):
    return isinstance(tag, str) and tag in outputs

Try / catch

try:
    out = split_transform(pc)
except ValueError as e:
    raise ConfigError(f'partition tags must match outputs: {e}') from e

Prevention

When it happens

Trigger: The `by` callable returns a string that is not a key in the transform's `outputs` mapping, while `unknown_output` is unset.

Common situations: Typo in the tag returned by the partition function vs. the declared outputs list; outputs renamed in the YAML spec but the function still returns old names; case mismatch ('A' vs 'a').

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/4912e95c5e09df70. Report an issue: GitHub.