apache/beam · error · ValueError

micros implies microsecond precision (6) but precision was

Error message

micros implies microsecond precision (6) but precision was %d; use subseconds instead.

What it means

When `micros` is given to Timestamp.__init__, precision must equal Timestamp.MICROS_PRECISION (6), because micros inherently encode microsecond resolution. Any other precision raises this ValueError suggesting you use `subseconds` with the desired precision instead.

Solutions

  1. Use subseconds=micros_value with the desired precision instead of micros
  2. Or drop the precision argument and accept the default microsecond precision (6) when using micros
  3. Set precision=Timestamp.MICROS_PRECISION explicitly if micros must be used

Example fix

// before
Timestamp(micros=100, precision=9)
// after
Timestamp(subseconds=100, precision=9)
Defensive patterns

Strategy: validation

Validate before calling

if micros is not None and precision != Timestamp.MICROS_PRECISION:
    kwargs = dict(subseconds=micros, precision=precision)
else:
    kwargs = dict(micros=micros)

Try / catch

try:
    ts = Timestamp(micros=m, precision=p)
except ValueError:
    ts = Timestamp(subseconds=m, precision=p)

Prevention

When it happens

Trigger: Timestamp(micros=100, precision=9) or Timestamp(micros=100, precision=0); code that parameterizes precision but passes micros regardless of it.

Common situations: Generic timestamp helpers that thread a precision config value through while using the micros shortcut; migrating code from micros to nanosecond precision without switching to subseconds.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at sdks/python/apache_beam/utils/timestamp.py:105

          'Cannot interpret %s %s as subseconds.' %
          (subseconds, type(subseconds)))
    if not isinstance(precision, int):
      raise TypeError(
          'Cannot interpret %s %s as precision.' % (precision, type(precision)))
    if not 0 <= precision <= Timestamp.NANOS_PRECISION:
      raise ValueError(
          'Timestamp precision must be between 0 and %d (inclusive), '
          'but was %d.' % (Timestamp.NANOS_PRECISION, precision))
    if micros is not None:
      if not isinstance(micros, (int, float)):
        raise TypeError(
            'Cannot interpret %s %s as micros.' % (micros, type(micros)))
      if subseconds:
        raise ValueError(
            'micros and subseconds are mutually exclusive, got micros=%s, '
            'subseconds=%s.' % (micros, subseconds))
      if precision != Timestamp.MICROS_PRECISION:
        raise ValueError(
            'micros implies microsecond precision (6) but precision was %d; '
            'use subseconds instead.' % precision)
      subseconds = micros
    self._precision = precision
    total = int(seconds * _POW_10[precision]) + int(subseconds)
    self._seconds, self._subseconds = divmod(total, _POW_10[precision])

  def _total(self, precision: int) -> int:
    """Returns the total time since the epoch in units of 10**-precision
    seconds.

    ``precision`` must be greater than or equal to this timestamp's
    precision, so that scaling up is always lossless.
    """
    return self._seconds * _POW_10[precision] + (
        self._subseconds * _POW_10[precision - self._precision])

  @staticmethod

View on GitHub (pinned to 12126d8942)