{"record":{"id":"cc6aa25321ac26fe","repo":"apache/beam","slug":"r-cannot-be-represented-exactly-at-precision-d-set-allow","errorCode":null,"errorMessage":"%r cannot be represented exactly at precision %d. Set allow_lossy_conversion=True to truncate it.","messagePattern":"%r cannot be represented exactly at precision (.+?)\\. Set allow_lossy_conversion=True to truncate it\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/utils/timestamp.py","lineNumber":267,"sourceCode":"\n    Increasing precision is always lossless. Decreasing precision raises\n    ValueError if this timestamp has a non-zero component below the target\n    precision, unless allow_lossy_conversion is True, in which case the\n    timestamp is truncated (floored) to the target precision.\n    \"\"\"\n    if precision == self._precision:\n      return self\n    if not 0 <= precision <= Timestamp.NANOS_PRECISION:\n      raise ValueError(\n          'Timestamp precision must be between 0 and %d (inclusive), '\n          'but was %d.' % (Timestamp.NANOS_PRECISION, precision))\n    if precision > self._precision:\n      scale = _POW_10[precision - self._precision]\n      return Timestamp(self._seconds, self._subseconds * scale, precision)\n    scale = _POW_10[self._precision - precision]\n    remainder = self._subseconds % scale\n    if remainder and not allow_lossy_conversion:\n      raise ValueError(\n          '%r cannot be represented exactly at precision %d. Set '\n          'allow_lossy_conversion=True to truncate it.' % (self, precision))\n    return Timestamp(self._seconds, self._subseconds // scale, precision)\n\n  def predecessor(self) -> 'Timestamp':\n    \"\"\"Returns the largest timestamp smaller than self, at this precision.\"\"\"\n    return Timestamp(self._seconds, self._subseconds - 1, self._precision)\n\n  def successor(self) -> 'Timestamp':\n    \"\"\"Returns the smallest timestamp larger than self, at this precision.\"\"\"\n    return Timestamp(self._seconds, self._subseconds + 1, self._precision)\n\n  def __repr__(self) -> str:\n    total = self._total(self._precision)\n    sign = ''\n    if total < 0:\n      sign = '-'\n      total = -total","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/utils/timestamp.py#L249-L285","documentation":"Timestamp.to_precision() refuses to narrow a timestamp's precision when doing so would discard non-zero digits, unless you pass allow_lossy_conversion=True. This prevents silently losing sub-unit data when truncating (flooring) to a coarser precision.","triggerScenarios":"Calling ts.to_precision(p) with p < ts._precision when the truncated subsecond digits are non-zero and allow_lossy_conversion is not set, e.g. Timestamp(0, 500_000_000, 9).to_precision(6).","commonSituations":"Downsampling nanosecond-precision event timestamps to microsecond windows; converting beam timestamps to external systems that only store micros; user code that assumes truncation is silent like Python's int().","solutions":["Pass allow_lossy_conversion=True if truncation is acceptable: ts.to_precision(6, allow_lossy_conversion=True).","Check first whether the conversion is lossless (e.g. compare nanos % 1000 == 0) and handle the remainder explicitly.","Keep the timestamp at its original precision and only round at output/formatting time (to_rfc3339)."],"exampleFix":"// before\nmicro_ts = nano_ts.to_precision(6)\n// after\nmicro_ts = nano_ts.to_precision(6, allow_lossy_conversion=True)","handlingStrategy":"validation","validationCode":"def truncatable(ts, target):\n    return ts.precision <= target or ts.nanos % (10 ** (ts.precision - target)) == 0","typeGuard":null,"tryCatchPattern":"try:\n    return ts.to_precision(target)\nexcept ValueError:\n    return ts.to_precision(target, allow_lossy_conversion=True)","preventionTips":["Decide your truncation policy once and pass allow_lossy_conversion=True explicitly.","Check for a non-zero remainder before narrowing precision if losslessness matters.","Keep full precision internally; round only at output boundaries."],"tags":["python","apache-beam","timestamp","precision-loss"],"backgroundTag":"value-out-of-range","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}