apache/beam · error · RuntimeError

cannot convert the micro seconds to

Error message

cannot convert the micro seconds to %s

What it means

from_micros converts microseconds into a protobuf Duration or Timestamp. If the target class is neither duration_pb2.Duration nor timestamp_pb2.Timestamp, Beam raises RuntimeError because the conversion is undefined for other proto types.

Solutions

  1. Pass duration_pb2.Duration or timestamp_pb2.Timestamp as the target class
  2. Check that the variable holding the class is not None or shadowed
  3. Convert manually with result.FromMicroseconds(micros) for supported protos

Example fix

// before
proto_utils.from_micros(micros, datetime)
// after
proto_utils.from_micros(micros, timestamp_pb2.Timestamp)
Defensive patterns

Strategy: type-guard

Validate before calling

if cls not in (duration_pb2.Duration, timestamp_pb2.Timestamp):
    raise ValueError(f'unsupported proto class {cls}')

Type guard

def is_convertible_proto(cls):
    return cls in (duration_pb2.Duration, timestamp_pb2.Timestamp)

Try / catch

try:
    ts = proto_utils.from_micros(micros, cls)
except RuntimeError as e:
    logging.error('bad proto class: %s', e)
    ts = timestamp_pb2.Timestamp()  # or re-raise

Prevention

When it happens

Trigger: Calling proto_utils.from_micros(micros, SomeClass) where SomeClass is not duration_pb2.Duration or timestamp_pb2.Timestamp (Protobuf 5.x enforces a max timestamp, but the else branch is about the type itself).

Common situations: Refactoring code to a custom timestamp proto; passing a Python datetime class or wrong protobuf message type by mistake; API changes swapping the expected proto 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/2a86a203f15fcc25. Report an issue: GitHub.

Appendix: source

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

  msg = struct_pb2.Struct()
  for key, value in kwargs.items():
    msg[key] = value  # pylint: disable=unsubscriptable-object, unsupported-assignment-operation
  return msg


def from_micros(cls: type[TimeMessageT], micros: int) -> TimeMessageT:
  result = cls()
  if isinstance(result, duration_pb2.Duration):
    result.FromMicroseconds(micros)
    return result
  # 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(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)

View on GitHub (pinned to 12126d8942)