apache/beam · error · RuntimeError

cannot convert to micro seconds

Error message

cannot convert %s to micro seconds

What it means

to_micros converts a protobuf Duration or Timestamp to integer microseconds. Passing any other object falls through the isinstance checks and raises RuntimeError, since no conversion is defined for that type.

Solutions

  1. Convert the value to a protobuf Timestamp first (e.g. to_Timestamp(time.time()))
  2. Pass only duration_pb2.Duration or timestamp_pb2.Timestamp values
  3. Check the source of the value — a schema/parse change may have altered its type

Example fix

// before
micros = proto_utils.to_micros(time.time())
// after
micros = proto_utils.to_micros(proto_utils.to_Timestamp(time.time()))
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(value, (duration_pb2.Duration, timestamp_pb2.Timestamp)):
    raise TypeError(f'expected Duration/Timestamp, got {type(value).__name__}')

Type guard

def is_micros_convertible(value):
    return isinstance(value, (duration_pb2.Duration, timestamp_pb2.Timestamp))

Try / catch

try:
    micros = proto_utils.to_micros(value)
except RuntimeError as e:
    logging.error('cannot convert to micros: %s', e)
    micros = proto_utils.to_micros(proto_utils.to_Timestamp(time.time()))

Prevention

When it happens

Trigger: Calling proto_utils.to_micros(value) with a datetime, int, float, or non-Duration/non-Timestamp protobuf message.

Common situations: Mixing time.time() floats and protobuf timestamps; refactors changing function signatures; reading a Timestamp from one proto and passing a nested field of the wrong type.

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/2921f4e063a04de1. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/utils/proto_utils.py:142

  # maximum allowable timestamp, so we cannot use the built-in conversion.
  elif isinstance(result, timestamp_pb2.Timestamp):
    result.seconds = micros // _SECONDS_TO_MICROS
    result.nanos = (micros % _SECONDS_TO_MICROS) * _MICROS_TO_NANOS
    return result
  else:
    raise RuntimeError('cannot convert the micro seconds to %s' % cls)


def to_micros(value: Union[duration_pb2.Duration, timestamp_pb2.Timestamp]):
  if isinstance(value, duration_pb2.Duration):
    return value.ToMicroseconds()
  # Protobuf 5.x enforces a maximum timestamp value less than the Beam
  # maximum allowable timestamp, so we cannot use the built-in conversion.
  elif isinstance(value, timestamp_pb2.Timestamp):
    micros = value.seconds * _SECONDS_TO_MICROS
    return micros + (value.nanos // _MICROS_TO_NANOS)
  else:
    raise RuntimeError('cannot convert %s to micro seconds' % value)


def to_Timestamp(time: Union[int, float]) -> timestamp_pb2.Timestamp:
  """Convert a float returned by time.time() to a Timestamp.
  """
  seconds = int(time)
  nanos = int((time - seconds) * 10**9)
  return timestamp_pb2.Timestamp(seconds=seconds, nanos=nanos)


def from_Timestamp(timestamp: timestamp_pb2.Timestamp) -> float:
  """Convert a Timestamp to a float expressed as seconds since the epoch.
  """
  return timestamp.seconds + float(timestamp.nanos) / 10**9

View on GitHub (pinned to 12126d8942)