{"record":{"id":"4912e95c5e09df70","repo":"apache/beam","slug":"unknown-output-name-tag-from-by","errorCode":null,"errorMessage":"Unknown output name \"{tag}\" from {by}","messagePattern":"Unknown output name \"(.+?)\" from (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/yaml_mapping.py","lineNumber":823,"sourceCode":"  if error_output in outputs:\n    raise ValueError(\n        f'Error handling output \"{error_output}\" '\n        f'cannot be among the listed outputs {outputs}')\n  T = TypeVar('T')\n\n  def split(element):\n    tag = split_fn(element)\n    if tag is None:\n      tag = unknown_output\n    if not isinstance(tag, str):\n      raise ValueError(\n          f'Returned output name \"{tag}\" of type {type(tag)} '\n          f'from \"{by}\" must be a string.')\n    if tag not in outputs:\n      if unknown_output:\n        tag = unknown_output\n      else:\n        raise ValueError(f'Unknown output name \"{tag}\" from {by}')\n    return beam.pvalue.TaggedOutput(tag, element)\n\n  output_set = set(outputs)\n  if unknown_output:\n    output_set.add(unknown_output)\n  if error_output:\n    output_set.add(error_output)\n  mapping_transform = beam.Map(split)\n  if error_output:\n    mapping_transform = mapping_transform.with_exception_handling(\n        **exception_handling_args(error_handling))\n  else:\n    mapping_transform = mapping_transform.with_outputs(*output_set)\n  splits = pcoll | mapping_transform.with_input_types(T).with_output_types(T)\n  result = {out: getattr(splits, out) for out in output_set}\n  for tag, out in result.items():\n    if tag != error_output:\n      out.element_type = pcoll.element_type","sourceCodeStart":805,"sourceCodeEnd":841,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/yaml_mapping.py#L805-L841","documentation":"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.","triggerScenarios":"The `by` callable returns a string that is not a key in the transform's `outputs` mapping, while `unknown_output` is unset.","commonSituations":"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').","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."],"exampleFix":"// before\ndef split(row): return 'high_value' if row.total > 100 else 'lowvalue'\n// after\ndef split(row): return 'high_value' if row.total > 100 else 'low_value'  # matches outputs: [high_value, low_value]","handlingStrategy":"validation","validationCode":"def check_outputs(fn, sample_row, outputs):\n    tag = fn(sample_row)\n    assert isinstance(tag, str) and tag in outputs, f'tag {tag!r} not in {sorted(outputs)}'","typeGuard":"def is_known_output(tag, outputs):\n    return isinstance(tag, str) and tag in outputs","tryCatchPattern":"try:\n    out = split_transform(pc)\nexcept ValueError as e:\n    raise ConfigError(f'partition tags must match outputs: {e}') from e","preventionTips":["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."],"tags":["python","apache-beam","yaml","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}