{"record":{"id":"8402cedf34f959e5","repo":"apache/beam","slug":"either-data-r-or-attributes-r-must-be-set","errorCode":null,"errorMessage":"Either data (%r) or attributes (%r) must be set.","messagePattern":"Either data \\(%r\\) or attributes \\(%r\\) must be set\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/gcp/pubsub.py","lineNumber":97,"sourceCode":"      and service generated attributes (such as id_label and\n      timestamp_attribute). May be None.\n    message_id: (str) ID of the message, assigned by the pubsub service when the\n      message is published. Guaranteed to be unique within the topic. Will be\n      reset to None if the message is being written to pubsub.\n    publish_time: (datetime) Time at which the message was published. Will be\n      reset to None if the Message is being written to pubsub.\n    ordering_key: (str) If non-empty, identifies related messages for which\n      publish order is respected by the PubSub subscription.\n  \"\"\"\n  def __init__(\n      self,\n      data,\n      attributes,\n      message_id=None,\n      publish_time=None,\n      ordering_key=\"\"):\n    if data is None and not attributes:\n      raise ValueError(\n          'Either data (%r) or attributes (%r) must be set.', data, attributes)\n    self.data = data\n    self.attributes = attributes\n    self.message_id = message_id\n    self.publish_time = publish_time\n    self.ordering_key = ordering_key\n\n  def __hash__(self):\n    return hash((self.data, frozenset(self.attributes.items())))\n\n  def __eq__(self, other):\n    return isinstance(other, PubsubMessage) and (\n        self.data == other.data and self.attributes == other.attributes)\n\n  def __repr__(self):\n    return 'PubsubMessage(%s, %s)' % (self.data, self.attributes)\n\n  @staticmethod","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/gcp/pubsub.py#L79-L115","documentation":"PubsubMessage.__init__ requires at least one of data or non-empty attributes. If data is None and attributes is empty/None, a message would carry no payload or metadata at all, which is invalid for Pub/Sub, so ValueError is raised. Note this raise uses %-style formatting arguments, so the rendered message may appear odd, but the condition is straightforward.","triggerScenarios":"Creating PubsubMessage(data=None, attributes=None or {}) — e.g. a DoFn emitting a message from a record whose payload failed to parse and whose attribute map defaulted to empty.","commonSituations":"Downstream of parsing failures where both payload and attributes end up None/empty; copy-pasted message construction without setting fields; mapping code that filters out attributes and yields data=None.","solutions":["Ensure at least one of data or attributes is set before constructing: provide a payload, or pass non-empty attributes.","Guard the emitting DoFn: skip records that produced neither payload nor attributes.","Use a default payload (e.g. b'' if the API permits) only when truly intended; better to fail upstream with a clearer error."],"exampleFix":"// before\nyield PubsubMessage(data=parsed.get('data'), attributes=parsed.get('attrs'))  # both may be None\n// after\nif parsed.get('data') is not None or parsed.get('attrs'):\n  yield PubsubMessage(data=parsed.get('data'), attributes=parsed.get('attrs'))","handlingStrategy":"validation","validationCode":"if data is None and not attributes:\n    raise ValueError('PubsubMessage needs data or non-empty attributes')","typeGuard":"def is_publishable(data, attributes):\n    return data is not None or bool(attributes)","tryCatchPattern":"try:\n    msg = PubsubMessage(data=data, attributes=attrs)\nexcept ValueError as e:\n    if 'Either data' in str(e):\n        log.warning('Skipping record with no payload and no attributes')\n    else:\n        raise","preventionTips":["Check source records for payload parse failures before constructing messages","Never emit PubsubMessage with both fields defaulted","Add unit tests for DoFns covering empty-record edge cases"],"tags":["pubsub","validation","empty-message","python","apache-beam"],"backgroundTag":"empty-required-field","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"}