apache/beam · error · ValueError
"IQR.score_one expected univariate input, but got
Error message
"IQR.score_one expected univariate input, but got %s", str(x)
What it means
IQR.score_one computes the anomaly score for one data point and expects a univariate beam.Row with exactly one field. If the row's __dict__ does not have exactly one entry, a ValueError is raised. This ensures scoring uses a single numeric value as the IQR math requires.
Solutions
- Map the input to a single-field Row before scoring: beam.Map(lambda r: beam.Row(value=r.metric)).
- Keep learn_one and score_one inputs shaped identically (same single field).
- Choose a multivariate detector if scoring requires multiple simultaneous features.
Example fix
// before rows | beam.Map(detector.score_one) // after rows | beam.Map(lambda r: beam.Row(v=r.metric)) | beam.Map(detector.score_one)
Defensive patterns
Strategy: validation
Validate before calling
if len(row.__dict__) != 1:
raise ValueError(f"IQR.score_one requires exactly one field, got: {list(row.__dict__)}") Type guard
def is_univariate(row): return len(getattr(row, '__dict__', {})) == 1 Try / catch
try:
score = detector.score_one(row)
except ValueError as e:
score = None
logger.warning("unscorable row %r: %s", row, e) Prevention
- Project rows to one numeric field immediately before scoring
- Mirror the learn-stage projection in the score stage
- Filter out metadata columns before detector transforms
When it happens
Trigger: Scoring a beam.Row containing multiple attributes or an empty row via IQR.score_one, typically when the same PCollection feeding learn_one was reshaped or when scoring rows straight from a multi-column source.
Common situations: Pipeline reads a table with several numeric columns and pipes all of them into score_one; schema evolution adds a column; users pass the original row instead of a projected single-value Row.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- "IQR.learn_one expected univariate input, but got
- "RobustZScore.learn_one expected univariate input, but got
- "RobustZScore.score_one expected univariate input, but got
- ZScore.learn_one expected univariate input, but got
- ZScore.score_one expected univariate input, but got
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/bd77914446d982e7.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/ml/anomaly/detectors/iqr.py:104
if len(x.__dict__) != 1:
raise ValueError(
"IQR.learn_one expected univariate input, but got %s", str(x))
v = next(iter(x))
self._q1_tracker.push(v)
self._q3_tracker.push(v)
def score_one(self, x: beam.Row) -> Optional[float]:
"""Scores a data point based on its deviation from the IQR.
Args:
x: A `beam.Row` containing a single numerical value.
Returns:
float | None: The anomaly score.
"""
if len(x.__dict__) != 1:
raise ValueError(
"IQR.score_one expected univariate input, but got %s", str(x))
v = next(iter(x))
if v is None or math.isnan(v):
return None
q1 = self._q1_tracker.get()
q3 = self._q3_tracker.get()
# not enough data points to compute median or median absolute deviation
if math.isnan(q1) or math.isnan(q3):
return float('NaN')
iqr = q3 - q1
if abs(iqr) < EPSILON:
return 0.0
if v > q3:View on GitHub (pinned to 12126d8942)