apache/beam · error · TypeError
Only one of topic and subscription may be specified.
Error message
Only one of topic and subscription may be specified.
What it means
read_from_pubsub validates its arguments: both 'topic' and 'subscription' were given, but a Pub/Sub read binds to exactly one of them; the guard fires at graph construction before any subscription is created.
Source
Thrown at sdks/python/apache_beam/yaml/yaml_io.py:388
deduplication of messages. If not provided, we cannot guarantee
that no duplicate data will be delivered on the Pub/Sub stream. In this
case, deduplication of the stream will be strictly best effort.
timestamp_attribute: Message value to use as element timestamp. If None,
uses message publishing time as the timestamp.
Timestamp values should be in one of two formats:
- A numerical value representing the number of milliseconds since the
Unix epoch.
- A string in RFC 3339 format, UTC timezone. Example:
``2015-10-29T23:41:41.123Z``. The sub-second component of the
timestamp is optional, and digits beyond the first three (i.e., time
units smaller than milliseconds) may be ignored.
publish_time_field: Field to add to output messages with the Pub/Sub
message publish time. If None, no such field is added.
"""
if topic and subscription:
raise TypeError('Only one of topic and subscription may be specified.')
elif not topic and not subscription:
raise TypeError('One of topic or subscription may be specified.')
if publish_time_field is not None and not publish_time_field.strip():
raise ValueError('publish_time_field must be a non-empty field name.')
has_publish_time_field = publish_time_field is not None
payload_schema, parser = _create_parser(format, schema)
extra_fields: list[schema_pb2.Field] = []
if not attributes and not attributes_map and not has_publish_time_field:
mapper = lambda msg: parser(msg)
else:
if isinstance(attributes, str):
attributes = [attributes]
if attributes:
extra_fields.extend(
[schemas.schema_field(attr, str) for attr in attributes])
if attributes_map:
extra_fields.append(
schemas.schema_field(attributes_map, Mapping[str, str]))View on GitHub (pinned to 12126d8942)
Solutions
- Specify only the subscription (it already determines the topic)
- Or specify only the topic to let Beam create/use an ephemeral path
- Remove the redundant key from your YAML/config before calling
Example fix
// before read_from_pubsub(topic='projects/p/topics/t', subscription='projects/p/subs/s') // after read_from_pubsub(subscription='projects/p/subs/s')
Defensive patterns
Strategy: validation
Validate before calling
if bool(topic) and bool(subscription):
raise ValueError('Pass only one of topic or subscription') Try / catch
try:
read_from_pubsub(topic=t, subscription=s)
except TypeError as e:
if 'Only one of topic' in str(e):
read_from_pubsub(subscription=s) Prevention
- Prefer subscription-only config for durable reads
- Sanitize templated config so stale keys do not persist
- Validate mutually exclusive args at config load time
When it happens
Trigger: Calling read_from_pubsub(topic=..., subscription=...) with both arguments truthy.
Common situations: Config templating fills in both keys; users paste a subscription path while also keeping the topic argument from earlier config.
Related errors
- RAW format does not take a schema
- STRING format does not take a schema
- Either data (%r) or attributes (%r) must be set.
- A pubsub message data field must not exceed 10MB
- A pubsub message must not have more than 100 attributes.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/0023181661c05881.
Report an issue: GitHub.