{"record":{"id":"3553b60ee0fcd468","repo":"apache/beam","slug":"tag-s-is-neither-the-main-tag-s-nor-any-of-the-tags-s","errorCode":null,"errorMessage":"Tag '%s' is neither the main tag '%s' nor any of the tags %s","messagePattern":"Tag '(.+?)' is neither the main tag '(.+?)' nor any of the tags (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/pvalue.py","lineNumber":293,"sourceCode":"\n  def __getattr__(self, tag: str) -> PCollection:\n    # Special methods which may be accessed before the object is\n    # fully constructed (e.g. in unpickling).\n    if tag[:2] == tag[-2:] == '__':\n      return object.__getattr__(self, tag)  # type: ignore\n    return self[tag]\n\n  def __getitem__(self, tag: Union[int, str, None]) -> PCollection:\n    # Accept int tags so that we can look at Partition tags with the\n    # same ints that we used in the partition function.\n    # TODO(gildea): Consider requiring string-based tags everywhere.\n    # This will require a partition function that does not return ints.\n    if isinstance(tag, int):\n      tag = str(tag)\n    if tag == self._main_tag:\n      tag = None\n    elif self._tags and tag not in self._tags and not self._allow_unknown_tags:\n      raise ValueError(\n          \"Tag '%s' is neither the main tag '%s' \"\n          \"nor any of the tags %s\" % (tag, self._main_tag, self._tags))\n    # Check if we accessed this tag before.\n    if tag in self._pcolls:\n      return self._pcolls[tag]\n\n    assert self.producer is not None\n    if tag is not None:\n      self._transform.output_tags.add(tag)\n      is_bounded = all(i.is_bounded for i in self.producer.main_inputs.values())\n      pcoll = PCollection(\n          self._pipeline,\n          tag=tag,\n          element_type=self._tagged_output_types.get(tag, typehints.Any),\n          is_bounded=is_bounded)\n      # Transfer the producer from the DoOutputsTuple to the resulting\n      # PCollection.\n      pcoll.producer = self.producer.parts[0]","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/pvalue.py#L275-L311","documentation":"ValueError raised by DoOutputsTuple.__getitem__ when indexing a multi-output PCollection tuple with a tag that is neither the main tag nor one of the declared side-output tags, and unknown tags are not allowed. It protects against typos in side-output tag access.","triggerScenarios":"Accessing results['typo_tag'] on the output of a DoFn using beam.tag_output(...) with tags like 'errors'; using an int not emitted via with_outputs declared tags; indexing a tag removed after refactoring.","commonSituations":"Renaming side-output tags in a DoFn without updating downstream accesses; confusing main output (tag None/'') with declared tags.","solutions":["Use one of the exact tags declared in DoFn.with_outputs(...) / emitted with beam.tag_output","Check available tags by inspecting the DoFn's output tags before indexing","Declare with_outputs('*', *extra_tags) or allow_unknown_tags=True if dynamic tags are intended"],"exampleFix":"// before\nmain, bad = results['main'], results['badd']\n// after\nmain, bad = results[None], results['bad']","handlingStrategy":"validation","validationCode":"declared = set(dofn.with_outputs_tags) | {None}\nassert tag in declared, f'{tag} not in {declared}'","typeGuard":null,"tryCatchPattern":"try:\n    bad = results['bad']\nexcept ValueError as e:\n    logging.error('Bad side-output tag: %s', e)\n    bad = results[None]","preventionTips":["Define side-output tags as module-level string constants shared by DoFn and consumers","List declared tags before indexing when tags may have changed","Use results.main (or results[None]) for the primary output instead of guessing tags"],"tags":["python","apache-beam","side-outputs","keyerror"],"backgroundTag":"invalid-enum-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"}