apache/beam · error · ValueError

No detectors found at

Error message

No detectors found at {model_uuid}

What it means

The Beam ML anomaly ensemble transform DoFn's expand() requires the EnsembleAnomalyDetector to have a non-empty _sub_detectors list. An empty list means there is nothing to fan out to, so it raises ValueError with the generated model_uuid for traceability.

Solutions

  1. Pass at least one sub-detector: EnsembleAnomalyDetector(detectors=[ZScore(...), ...])
  2. Validate the detector list is non-empty before building the pipeline
  3. Fix the config-loading logic that produced an empty detectors collection

Example fix

// before
ens = EnsembleAnomalyDetector(detectors=[])

// after
detectors = [ZScore(window_size=100), StandardDeviation(window_size=100)]
if not detectors:
    raise ValueError('at least one detector required')
ens = EnsembleAnomalyDetector(detectors=detectors)
Defensive patterns

Strategy: validation

Validate before calling

if not ensemble._sub_detectors:
    raise ValueError('EnsembleAnomalyDetector requires at least one sub-detector')

Type guard

def has_detectors(d) -> bool:
    subs = getattr(d, '_sub_detectors', None)
    return isinstance(subs, list) and len(subs) > 0

Try / catch

try:
    result = pipeline | ensemble_transform
except ValueError as e:
    if 'No detectors found' in str(e):
        logging.error('Configure at least one sub-detector: %s', e)

Prevention

When it happens

Trigger: Constructing EnsembleAnomalyDetector(detectors=[]) (or equivalent aggregate detector like majority_vote/zscore with empty detector list) and running it through the ensemble transform.

Common situations: Building the detector list dynamically from config where all detectors were filtered out; YAML/JSON config parsed to an empty list; default constructor called without detectors.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at sdks/python/apache_beam/ml/anomaly/transforms.py:521

  """Runs an ensemble of anomaly detectors on a PCollection of data.

  This PTransform applies an `EnsembleAnomalyDetector` to the input data,
  running each sub-detector and aggregating the results.

  Args:
    ensemble_detector: The `EnsembleAnomalyDetector` to run.
  """
  def __init__(self, ensemble_detector: EnsembleAnomalyDetector):
    self._ensemble_detector = ensemble_detector

  def expand(
      self, input: beam.PCollection[NestedKeyedInputT]
  ) -> beam.PCollection[NestedKeyedOutputT]:
    model_uuid = f"{self._ensemble_detector._model_id}:{uuid.uuid4().hex[:6]}"

    assert self._ensemble_detector._sub_detectors is not None
    if not self._ensemble_detector._sub_detectors:
      raise ValueError(f"No detectors found at {model_uuid}")

    results = []
    for idx, detector in enumerate(self._ensemble_detector._sub_detectors):
      if isinstance(detector, EnsembleAnomalyDetector):
        results.append(
            input
            | f"Run Ensemble Detector at index {idx} ({model_uuid})" >>
            RunEnsembleDetector(detector))
      elif isinstance(detector, OfflineDetector):
        results.append(
            input
            | f"Run Offline Detector at index {idx} ({model_uuid})" >>
            RunOfflineDetector(detector))
      else:
        results.append(
            input
            | f"Run One Detector at index {idx} ({model_uuid})" >>
            RunOneDetector(detector))

View on GitHub (pinned to 12126d8942)