apache/beam · error · TypeError

Cannot interpret as precision.

Error message

Cannot interpret %s %s as precision.

What it means

Timestamp.__init__ validates that the `precision` argument is an integer. If you pass precision as a float, string, or None, a TypeError is raised because precision must be a whole count of fractional digits (0-9). The library throws this to fail fast before computing nanosecond-resolution values with an invalid precision type.

Solutions

  1. Pass precision as a Python int, e.g. Timestamp(seconds=1.5, precision=6)
  2. Coerce with int(): Timestamp(..., precision=int(precision))
  3. If parsing from config, validate the value with isinstance(precision, int) first

Example fix

// before
Timestamp(seconds=1.5, precision=float(cfg.precision))
// after
Timestamp(seconds=1.5, precision=int(cfg.precision))
Defensive patterns

Strategy: validation

Validate before calling

if not isinstance(precision, int) or not 0 <= precision <= 9:
    raise ValueError(f'precision must be int in [0,9], got {precision!r}')

Type guard

def is_valid_precision(p) -> bool:
    return isinstance(p, int) and 0 <= p <= Timestamp.NANOS_PRECISION

Prevention

When it happens

Trigger: Calling Timestamp(seconds=..., precision='6') or precision=6.0 or precision=None directly or via from_rfc3339-style helpers that pass a non-int precision.

Common situations: Parsing precision from JSON/YAML config where numbers deserialize as floats or strings; passing len(fraction_digits) from a string as str; arithmetic like precision//2 in Python 2 producing floats.

Related errors


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

Appendix: source

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

  MICROS_PRECISION = 6
  NANOS_PRECISION = 9

  def __init__(
      self,
      seconds: Union[int, float] = 0,
      subseconds: Union[int, float] = 0,
      precision: int = MICROS_PRECISION,
      *,
      micros: Optional[Union[int, float]] = None) -> None:
    if not isinstance(seconds, (int, float)):
      raise TypeError(
          'Cannot interpret %s %s as seconds.' % (seconds, type(seconds)))
    if not isinstance(subseconds, (int, float)):
      raise TypeError(
          '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

View on GitHub (pinned to 12126d8942)