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.

Solutions

  1. Specify only the subscription (it already determines the topic)
  2. Or specify only the topic to let Beam create/use an ephemeral path
  3. 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

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


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/0023181661c05881. Report an issue: GitHub.

Appendix: 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)