{"record":{"id":"5c8c4f61229faa65","repo":"apache/beam","slug":"the-maximum-allowed-number-of-gcs-custom-audit-entries-5c8c4f","errorCode":null,"errorMessage":"The maximum allowed number of GCS custom audit entries (including the default x-goo-custom-audit-job) is %d.","messagePattern":"The maximum allowed number of GCS custom audit entries \\(including the default x-goo-custom-audit-job\\) is (.+?)\\.","errorType":"validation","errorClass":"argparse.ArgumentError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/options/pipeline_options.py","lineNumber":224,"sourceCode":"      setattr(namespace, self.dest, {})\n      self._custom_audit_entries = getattr(namespace, self.dest)\n\n    if option_string == '--gcs_custom_audit_entries':\n      # in the format of {\"key\": \"value\"}\n      assert (isinstance(values, str))\n      sub_entries = json.loads(values)\n      for key, value in sub_entries.items():\n        self._add_entry(key, value)\n    else:  # option_string == '--gcs_custom_audit_entry'\n      # in the format of 'key=value'\n      assert (isinstance(values, str))\n      parts = values.split('=', 1)\n      key = parts[0]\n      value = parts[1] if len(parts) > 1 else ''\n      self._add_entry(key, value)\n\n    if self._exceed_entry_limit():\n      raise argparse.ArgumentError(\n          None,\n          \"The maximum allowed number of GCS custom audit entries (including the default x-goo-custom-audit-job) is %d.\"  # pylint: disable=line-too-long\n          % _GcsCustomAuditEntriesAction.MAX_ENTRIES)\n\n\nclass _CommaSeparatedListAction(argparse.Action):\n  \"\"\"\n  Argparse Action that splits comma-separated values and appends them to\n  a list. This allows options like --experiments=abc,def to be treated\n  as separate experiments 'abc' and 'def', similar to how Java SDK handles\n  them.\n\n  If there are key=value experiments in a raw argument, the remaining part of\n  the argument are treated as values and won't split further. For example:\n  'abc,def,master_key=k1=v1,k2=v2' becomes\n  ['abc', 'def', 'master_key=k1=v1,k2=v2'].\n  \"\"\"\n  def __call__(self, parser, namespace, values, option_string=None):","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/options/pipeline_options.py#L206-L242","documentation":"The GCS custom audit entries argparse action enforces a maximum number of entries, counting the always-present default x-goo-custom-audit-job entry. Raising more entries than MAX_ENTRIES triggers this error so the job doesn't get rejected later by the service.","triggerScenarios":"Supplying more than _GcsCustomAuditEntriesAction.MAX_ENTRIES - 1 custom audit entries via the gcs_custom_audit_entries pipeline option (repeated key=value arguments).","commonSituations":"Bulk-attaching many audit labels to satisfy compliance tooling; generating audit entries in a loop from a config map without a cap.","solutions":["Reduce the number of custom audit entries to at most MAX_ENTRIES - 1","Merge related metadata into fewer, shorter entries","Keep the most important entries and move the rest to a separate tracking system"],"exampleFix":"// before\n--gcs_custom_audit_entries=k1=v1 k2=v2 k3=v3 k4=v4 k5=v5 ...\n// after\n--gcs_custom_audit_entries=k1=v1 k2=v2","handlingStrategy":"validation","validationCode":"entries = [f'{k}={v}' for k, v in audit_map.items()]\nassert len(entries) <= _GcsCustomAuditEntriesAction.MAX_ENTRIES - 1, 'too many audit entries'","typeGuard":"def within_entry_limit(entries):\n    return len(entries) < _GcsCustomAuditEntriesAction.MAX_ENTRIES","tryCatchPattern":"try:\n    parse_args(argv)\nexcept argparse.ArgumentError as ex:\n    print(f'too many audit entries: {ex}')\n    sys.exit(2)","preventionTips":["Cap the audit map at build time (e.g. dict slice)","Merge metadata into fewer entries","Test pipeline construction with the maximum allowed entries"],"tags":["python","argparse","cli","gcs","audit"],"backgroundTag":"value-out-of-range","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}