apache/beam · error · TypeError

'Expected int metric type but received %s with value %s' % (

Error message

'Expected int metric type but received %s with value %s' % (type(metric), metric)

What it means

int64_gauge encodes a LATEST_INT64 gauge MonitoringInfo where the payload is (timestamp_ms, value), so the metric argument must be a plain int. Passing any non-int raises TypeError immediately. The timestamp is generated internally, so callers only supply the integer value.

Source

Thrown at sdks/python/apache_beam/metrics/monitoring_infos.py:320

  return create_monitoring_info(
      USER_GAUGE_URN, LATEST_INT64_TYPE, payload, labels)


def int64_gauge(urn, metric, ptransform=None) -> metrics_pb2.MonitoringInfo:
  """Return the gauge monitoring info for the URN, metric and labels.

  Args:
    urn: The URN of the monitoring info/metric.
    metric: An int representing the value. The current time will be used for
            the timestamp.
    ptransform: The ptransform id used as a label.
  """
  labels = create_labels(ptransform=ptransform)
  if isinstance(metric, int):
    value = metric
    time_ms = int(time.time()) * 1000
  else:
    raise TypeError(
        'Expected int metric type but received %s with value %s' %
        (type(metric), metric))
  coder = coders.VarIntCoder()
  payload = coder.encode(time_ms) + coder.encode(value)
  return create_monitoring_info(urn, LATEST_INT64_TYPE, payload, labels)


def user_set_string(namespace, name, metric, ptransform=None):
  """Return the string set monitoring info for the URN, metric and labels.

  Args:
    namespace: User-defined namespace of StringSet.
    name: Name of StringSet.
    metric: The StringSetData representing the metrics.
    ptransform: The ptransform id used as a label.
  """
  labels = create_labels(ptransform=ptransform, namespace=namespace, name=name)
  if isinstance(metric, StringSetData):

View on GitHub (pinned to 12126d8942)

Solutions

  1. Pass a plain Python int: int64_gauge(urn, metric=int(value)).
  2. If you have a GaugeData with its own timestamp, call int64_user_gauge instead.
  3. Coerce with isinstance(metric, int) check (and int() cast) before calling.

Example fix

// before
mi = int64_gauge(urn, metric=str(value))
// after
mi = int64_gauge(urn, metric=int(value))
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(metric, int):
    metric = int(metric)

Type guard

def is_int_metric(m):
    return isinstance(m, int) and not isinstance(m, bool)

Try / catch

try:
    mi = int64_gauge(urn, metric=metric)
except TypeError as e:
    logger.error('int64_gauge requires an int: %s', e)
    raise

Prevention

When it happens

Trigger: Calling int64_gauge with a GaugeData instance, float, string, or None, e.g. int64_gauge('urn', metric=GaugeData(42)) — the mirror image of error 3148.

Common situations: Mixing up int64_gauge and int64_user_gauge, which have opposite metric-type requirements; passing numpy integers or Decimal values in code that assumes int compatibility; reading gauge values from config/JSON where they arrive as strings.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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