apache/beam · error · ValueError
Main output tag %r must be different from side output tags %
Error message
Main output tag %r must be different from side output tags %r.
What it means
When a ParDo declares multiple outputs, each output is identified by a tag. The main output tag and side output tags must be distinct namespaces; Beam raises this ValueError at transform validation time if the requested main tag collides with one of the side output tags.
Source
Thrown at sdks/python/apache_beam/transforms/core.py:1837
be used for the main output (which will not have a tag associated with
it).
Returns:
~apache_beam.pvalue.DoOutputsTuple: An object of type
:class:`~apache_beam.pvalue.DoOutputsTuple` that bundles together all
the outputs of a :class:`ParDo` transform and allows accessing the
individual :class:`~apache_beam.pvalue.PCollection` s for each output
using an ``object.tag`` syntax.
Raises:
TypeError: if the **self** object is not a
:class:`~apache_beam.pvalue.PCollection` that is the result of a
:class:`ParDo` transform.
ValueError: if **main_kw** contains any key other than
``'main'``.
"""
if main in tags:
raise ValueError(
'Main output tag %r must be different from side output tags %r.' %
(main, tags))
type_hints = self.get_type_hints()
declared_tags = set(type_hints.tagged_output_types().keys())
requested_tags = set(tags)
unknown = requested_tags - declared_tags
if unknown and declared_tags: # Only warn if type hints exist
logging.warning(
"Tags %s requested in with_outputs() but not declared "
"in type hints. Declared tags: %s",
unknown,
declared_tags)
return _MultiParDo(self, tags, main, allow_unknown_tags)
def _do_fn_info(self):
return DoFnInfo.create(self.fn, self.args, self.kwargs)
View on GitHub (pinned to 12126d8942)
Solutions
- Rename the colliding side output tag so it differs from the main tag.
- Explicitly choose a distinct main tag, e.g. with_outputs('side1', main='primary').
- Deduplicate/validate the tag list programmatically before calling with_outputs (set difference between tags and main).
Example fix
// before
pardo.with_outputs('main', 'main', 'other')
// after
pardo.with_outputs('main', 'side_main', 'other') Defensive patterns
Strategy: validation
Validate before calling
tags = ['side1', 'side2']
main = 'main'
assert main not in tags, f'main tag {main!r} collides with side tags {tags}' Type guard
def tags_are_disjoint(main, tags):
return main not in tags Try / catch
try:
pardo = pardo.with_outputs(*tags, main=main)
except ValueError as e:
logger.error('Output tag collision: %s', e)
raise Prevention
- Keep output tag names in module-level constants with a naming convention (e.g. side_ prefix).
- Deduplicate tag lists before calling with_outputs.
- Never use the default 'main' string as a side output tag.
When it happens
Trigger: Calling pardo.with_outputs('main', *side_tags) or with_outputs(tag, main='tag') where the main tag string is also present in the side output tags tuple.
Common situations: Copy-paste of tag strings; defaulting main='main' while also passing 'main' as a side tag; dynamically built tag lists that accidentally include the main tag.
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
- Transform '{full_label}' expects a PCollection as input. Got
- Returning a %s from a ParDo or FlatMap is not allowed. Pleas
- ParDo must be called with a DoFn instance.
- partial and use_subprocess are mutually incompatible.
- allow_unsafe_userstate_in_process is incompatible with excep
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/9c6eccaa81b3f4f6.
Report an issue: GitHub.