{"record":{"id":"6bc30baf3aea2b0b","repo":"apache/beam","slug":"metric-namespace-must-be-non-empty","errorCode":null,"errorMessage":"Metric namespace must be non-empty","messagePattern":"Metric namespace must be non-empty","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/metrics/metricbase.py","lineNumber":78,"sourceCode":"      namespace: Optional[str],\n      name: Optional[str],\n      urn: Optional[str] = None,\n      labels: Optional[dict[str, str]] = None) -> None:\n    \"\"\"Initializes ``MetricName``.\n\n    Note: namespace and name should be set for user metrics,\n    urn and labels should be set for an arbitrary metric to package into a\n    MonitoringInfo.\n\n    Args:\n      namespace: A string with the namespace of a metric.\n      name: A string with the name of a metric.\n      urn: URN to populate on a MonitoringInfo, when sending to RunnerHarness.\n      labels: Labels to populate on a MonitoringInfo\n    \"\"\"\n    if not urn:\n      if not namespace:\n        raise ValueError('Metric namespace must be non-empty')\n      if not name:\n        raise ValueError('Metric name must be non-empty')\n    self.namespace = namespace\n    self.name = name\n    self.urn = urn\n    self.labels = labels if labels else {}\n\n  def __eq__(self, other):\n    return (\n        self.namespace == other.namespace and self.name == other.name and\n        self.urn == other.urn and self.labels == other.labels)\n\n  def __str__(self):\n    if self.urn:\n      return 'MetricName(namespace={}, name={}, urn={}, labels={})'.format(\n          self.namespace, self.name, self.urn, self.labels)\n    else:  # User counter case.\n      return 'MetricName(namespace={}, name={})'.format(","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/metrics/metricbase.py#L60-L96","documentation":"apache_beam.metrics.metricbase.Metric's __init__ raises ValueError when a MonitoringInfo URN is not supplied and the namespace is empty. The namespace identifies which component owns the metric; without a URN, Beam relies on namespace+name to identify the metric, so an empty namespace is unusable. This is a fail-fast validation to prevent unidentifiable metrics.","triggerScenarios":"Creating a Metric (or subclass such as Metrics.counter/deprecated Counter/Meter) with namespace='' or None while omitting the urn argument.","commonSituations":"Passing a variable that is an empty string as namespace; building metrics dynamically where the namespace is computed and comes back empty; calling Metric directly instead of via the Metrics facade and forgetting namespace.","solutions":["Pass a non-empty namespace string, conventionally the class name or module that owns the metric, e.g. Metrics.counter(MyDoFn.__name__, 'elements_read').","If you intentionally have no namespace, supply a urn instead — when urn is set, namespace/name validation is skipped.","Guard dynamic namespace construction so empty results fall back to a default namespace string."],"exampleFix":"// before\n_ = Metrics.counter('', 'elements_read')\n// after\n_ = Metrics.counter('MyDoFn', 'elements_read')","handlingStrategy":"validation","validationCode":"if not urn and not namespace:\n    raise ValueError('namespace required when urn is not set')\nmetric = Metrics.counter(namespace, name)","typeGuard":null,"tryCatchPattern":"try:\n    metric = Metrics.counter(namespace, name)\nexcept ValueError as e:\n    metric = Metrics.counter('default-namespace', name)\n    logger.warning('metric namespace rejected (%s), using default', e)","preventionTips":["Always pass the owning class/module name as namespace (e.g. MyDoFn.__name__).","Never build namespaces from possibly-empty config values without a fallback."],"tags":["python","apache-beam","metrics","validation"],"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"}