{"record":{"id":"ed2d6dd64822211c","repo":"apache/beam","slug":"approximateunique-needs-a-size-16-for-an-error-0-50-in","errorCode":null,"errorMessage":"ApproximateUnique needs a size >= 16 for an error <= 0.50. In general, the estimation error is about 2 / sqrt(sample_size). Received {size = %s}.","messagePattern":"ApproximateUnique needs a size >= 16 for an error <= 0\\.50\\. In general, the estimation error is about 2 / sqrt\\(sample_size\\)\\. Received (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/stats.py","lineNumber":127,"sourceCode":"\n    :param size: an int not smaller than 16, which we would use to estimate\n      number of unique values.\n    :param error: max estimation error, which is a float between 0.01 and 0.50.\n      If error is given, sample size will be calculated from error with\n      _get_sample_size_from_est_error function.\n    :return: sample size\n    :raises:\n      ValueError: If both size and error are given, or neither is given, or\n      values are out of range.\n    \"\"\"\n\n    if None not in (size, error):\n      raise ValueError(ApproximateUnique._MULTI_VALUE_ERR_MSG % (size, error))\n    elif size is None and error is None:\n      raise ValueError(ApproximateUnique._NO_VALUE_ERR_MSG)\n    elif size is not None:\n      if not isinstance(size, int) or size < 16:\n        raise ValueError(ApproximateUnique._INPUT_SIZE_ERR_MSG % (size))\n      else:\n        return size\n    else:\n      if error < 0.01 or error > 0.5:\n        raise ValueError(ApproximateUnique._INPUT_ERROR_ERR_MSG % (error))\n      else:\n        return ApproximateUnique._get_sample_size_from_est_error(error)\n\n  @staticmethod\n  def _get_sample_size_from_est_error(est_err):\n    \"\"\"\n    :return: sample size\n\n    Calculate sample size from estimation error\n    \"\"\"\n    return math.ceil(4.0 / math.pow(est_err, 2.0))\n\n  @typehints.with_input_types(T)","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/stats.py#L109-L145","documentation":"When size is given, parse_input_params requires an int >= 16 because the estimation error is roughly 2/sqrt(sample_size); smaller samples exceed 0.50 error. A non-int or size < 16 triggers _INPUT_SIZE_ERR_MSG. (Note: strings are also rejected since isinstance(size, int) is checked.)","triggerScenarios":"beam.ApproximateUnique(size=10); beam.ApproximateUnique(size='1000') (string from config); size as float like 100.0 in strict type paths.","commonSituations":"Loading numeric options from CLI/JSON where they arrive as strings; users underestimating the minimum sample; copying examples with tiny sample sizes.","solutions":["Use an integer sample size >= 16, sized so 2/sqrt(size) meets your error tolerance (e.g. size=10000 gives ~2% error).","Convert config strings to int before passing (int(value)).","Prefer specifying error (0.01–0.50) and let _get_sample_size_from_est_error compute the sample size."],"exampleFix":"// before\nbeam.ApproximateUnique(size='100')\n// after\nbeam.ApproximateUnique(size=10000)  # int >= 16","handlingStrategy":"validation","validationCode":"if size is not None:\n    assert isinstance(size, int) and not isinstance(size, bool) and size >= 16, \\\n        f'size must be int >= 16, got {size!r}'","typeGuard":"def is_valid_sample_size(size) -> bool:\n    return isinstance(size, int) and not isinstance(size, bool) and size >= 16","tryCatchPattern":"try:\n    t = beam.ApproximateUnique(size=size)\nexcept ValueError as e:\n    if 'size >= 16' in str(e):\n        t = beam.ApproximateUnique(size=max(16, int(size) if size else 16))\n    else:\n        raise","preventionTips":["Cast config strings to int before constructing the transform.","Choose size >= 16, ideally 2/(target_error**2) for a given tolerance.","Prefer specifying error instead of a hand-picked sample size."],"tags":["python","apache-beam","approximateunique","value-out-of-range"],"backgroundTag":"argument-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"}