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_typeView on GitHub (pinned to 12126d8942)
Solutions
- Make the split function return exactly one of the strings listed in the transform's `outputs` mapping.
- Fix typos/casing mismatches between returned tags and declared output names.
- 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
- Keep output names in one shared constant list used by both the function and the YAML spec.
- Configure unknown_output as a fallback route for unmatched tags.
- Add a smoke test that runs the split fn over representative rows and asserts tags are declared.
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
- Node ID cannot be empty
- Edge source and target cannot be empty
- Incompatible types: {weak_schema['type']} vs {strong_schema[
- HuggingFacePipelineModelHandler requires either 'task' or 'm
- Unexpected parameters in model_handler: {extra_params}
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/4912e95c5e09df70.
Report an issue: GitHub.